Housekeeping in application with VS2005 squiggles!

R

Rob Meade

Hi all,

Ok - typically, in a function that returns as a boolean, if there's a bit of
database action going on I'll have a little tidy up process before exiting
the function.

I know .net is supposed to handle all of this stuff itself, but its a
practice I've always performed, and personally I like to know its been done!

So, as an example I'd have a little something like this..

Private Function testMeDo(ByVal myObject As Object) As Boolean

Dim Connection As SQLConnection
Dim Command As SQLCommand
Dim Parameters As ArrayList

' exception handling
Try

' do some database wizardy here...

' then tidy up (same as below) <--- no squiggles in here because
I've created instances of the objects and populated them

Catch ex As Exception

' tidy up
If Parameters Is Nothing = False Then
Parameters.Clear()
Parameters = Nothing
End If
If Command Is Nothing = False Then
Command.Dispose
Command = Nothing
End If
If Connection Is Nothing = False Then
Connection.Close()
Connection = Nothing
End If

End Try

End Function

Ok - now this is just a "quick" example - but, because I haven't created new
instances of of the objects I've declare outside of the Try within the
"Catch" section of my Try/Catch - it places a green squiggle under them and
tells me that it might generate a Null exception error...

Whilst this doesn't have a detrimental effect on my application (yet at
least!) - I'd like it to be "tidier" and therefore not have the squiggles!

Any thoughts anyone?

Cheers

Rob
 
S

Steve C. Orr [MVP, MCSD]

Try initializing them to nothing where they are declared, something like
this:

Dim Connection As SQLConnection = Nothing
Dim Command As SQLCommand = Nothing
Dim Parameters As ArrayList = Nothing
 
R

Rob Meade

....
Try initializing them to nothing where they are declared, something like
this:

Dim Connection As SQLConnection = Nothing
Dim Command As SQLCommand = Nothing
Dim Parameters As ArrayList = Nothing

Hi Steve,

Thanks for the reply.

Yes, I tried this, and obviously it removes the "squiggle" - my only
thought - and this relates to the way I was already doing it as much as your
example - but if I have a function thats supposed to get something in my
data layer, is it "acceptable" to return as a "nothing" of that object?

The reason I ask is because then where ever you use the object you have to
always test to see whether its nothing or not before you can use it.

Also - this kind applies to functions that return as Boolean for whether
they have been successful or not (lets say an update database function
etc) - if there's an error and it wasn't possible to update the database (in
this scenario) - then the function will return false - but you'll not get
what the error actually was in the return.

I was wonder whether I might be better of creating myself a custom "Result"
object, this would return a "true" or "false", but in addition be able to
return an exception, or at least the details from it to the calling code -
what do you think - is this the way typically people do this?

Regards

Rob
 
D

David Hogue

Rob said:
Yes, I tried this, and obviously it removes the "squiggle" - my only
thought - and this relates to the way I was already doing it as much as your
example - but if I have a function thats supposed to get something in my
data layer, is it "acceptable" to return as a "nothing" of that object?

I will often return Nothing from a function that is designed to fetch a
single record from the database. I return an empty collection in a
function that returns a list of objects if nothing matches the query.
The reason I ask is because then where ever you use the object you have to
always test to see whether its nothing or not before you can use it.

Yes, this can be a nuisance. Though if a database function returns
nothing it often means there was an error and I need to display a
message such as "Requested item was not found"
Also - this kind applies to functions that return as Boolean for whether
they have been successful or not (lets say an update database function
etc) - if there's an error and it wasn't possible to update the database (in
this scenario) - then the function will return false - but you'll not get
what the error actually was in the return.

I was wonder whether I might be better of creating myself a custom "Result"
object, this would return a "true" or "false", but in addition be able to
return an exception, or at least the details from it to the calling code -
what do you think - is this the way typically people do this?

These days it's more common to use exceptions than return values for
errors. If there is an exception at the database layer (can't contact
the database for example) that is often a problem that needs to be dealt
with at a higher level. You can catch an exception and add some
information to it if necessary, then rethrow it.

Also, in your initial example it looks like the tidy up code is
duplicated. Once in the try and then once in the catch. This can be
accomplished in a cleaner way with a try/finally block:

Try
' connect to database....
Finally
' tidy up
End Try

The Using keyword can also be useful in these situations:

Dim connection As SqlConnection
Try
connection = New SqlConnection(...)
connection.Open()
...
Finally
If connection IsNot Nothing Then
connection.Close()
connection = Nothing
End If
End Try

has the same results as this:

Using connection As SqlConnection = New SqlConnection(...)
connection.Open()
...
End Using

I hope this makes sense. It's a bit late for me to be posting
 
R

Rob Meade

...
Yes, this can be a nuisance. Though if a database function returns
nothing it often means there was an error and I need to display a
message such as "Requested item was not found"

Hi David,

Thanks for your reply - in the above, this is exactly what I mean though -
if you return to your user "Requested item was not found" for example -
based on getting nothing back - it might have been that your Try/Catch
around your database connectivity caught an exception and died gracefully
and return "nothing" as it were - as opposed to meaning that there was not a
matching record - this is the problem I'm having, it would be handy to
return more :eek:)
These days it's more common to use exceptions than return values for
errors. If there is an exception at the database layer (can't contact
the database for example) that is often a problem that needs to be dealt
with at a higher level. You can catch an exception and add some
information to it if necessary, then rethrow it.

But if there is an exception, or even if I throw one, I'm going to nneed to
handle it some how, and that some how is less likely to end up with a
populated object (as opposed to it equally nothing) - so where do I handle
the exception? I already have a try/catch around my database
connection/execution in the data layer, its just that at the moment, if it
catches an exception then it'll tidy up (close connections/dispose commands)
and then thats about it....so it dies gracefully but obviously the object
that would normally be returned from that function is still "nothing". In
the code that called it, and was expecting the object back - it doesn't know
at this stage whether its nothing becaues there was no match for example, or
nothing because of an exception...

Do I need to put another Try/Catch around the call to the function as well?
(seems to be an increasing amount of try/catches!
Also, in your initial example it looks like the tidy up code is
duplicated. Once in the try and then once in the catch. This can be
accomplished in a cleaner way with a try/finally block:

Yeah, I tried the "Finally" block before, but I came to the conclusion that
the Finally block never got hit if there had been an exception caught anyway
(am I wrong?) - therefore I plonked it in both...to be honest I use this in
so many places it should probably become another function that I call in
these places anyway instead of duplicating it all the time, and then just
handle any "other" items that need tidying up in each specific area.
The Using keyword can also be useful in these situations:
I hope this makes sense. It's a bit late for me to be posting

Erm - not quite :eek:)

How is it the same? It looks like you try to use an existing connection and
open it - in mine I'm looking to see if there is a connection object that
isn't nothing - and if there is, try to close it, and then kill it
off...I've probably misunderstood feel free to enlighten me :eek:)

Thanks again for your reply.

Regards

Rob
 
D

David Hogue

Hi Rob,

Rob said:
...


Hi David,

Thanks for your reply - in the above, this is exactly what I mean though -
if you return to your user "Requested item was not found" for example -
based on getting nothing back - it might have been that your Try/Catch
around your database connectivity caught an exception and died gracefully
and return "nothing" as it were - as opposed to meaning that there was not a
matching record - this is the problem I'm having, it would be handy to
return more :eek:)

Yeah, I return nothing if nothing is found, but throw an exception if
there is an error.
But if there is an exception, or even if I throw one, I'm going to nneed to
handle it some how, and that some how is less likely to end up with a
populated object (as opposed to it equally nothing) - so where do I handle
the exception? I already have a try/catch around my database
connection/execution in the data layer, its just that at the moment, if it
catches an exception then it'll tidy up (close connections/dispose commands)
and then thats about it....so it dies gracefully but obviously the object
that would normally be returned from that function is still "nothing". In
the code that called it, and was expecting the object back - it doesn't know
at this stage whether its nothing becaues there was no match for example, or
nothing because of an exception...

Do I need to put another Try/Catch around the call to the function as well?
(seems to be an increasing amount of try/catches!

Many exceptions can be handled with custom error pages and/or in global.asax

If the exception does need to be handled somewhere often it is several
function calls up and not in the calling function. Eventually you get a
system were every function returns an error message and every function
call needs to check the return value. This is how things worked before
exceptions came along.

I created a quick example of what I mean below. This might be a bit
extreme and if you have a simple way to handle exceptions that makes
sense for your app, do it that way. Simple is (almost) always better.

-------------------------------

Sub A()
Dim result As ReturnClass = B()
If result.HadError Then ...
End Sub

Function B() As ReturnClass
Dim result As ReturnClass = C()
If result.HadError Then ...
End Function

Function C() As ReturnClass
Dim result As ReturnClass = D()
If result.HadError Then ...
Else result.Foo...
End Function

Function D() As ReturnClass
Try
' open connection...
' result.Foo = foo
Catch
result.HadError = True
End Try
Return result
End Function

vs.----------------------------

Sub A()
Try
B()
Catch ex As Exception
...
End Try
End Sub

Sub B()
C()
...
End Sub

Sub C()
Dim c As Foo = D()
...
End Sub

Function D() As Foo
Try
' open connection...
' return foo
Catch ex As Exception
Throw New MyException("error getting row " + id, ex)
End Try
End Function

-------------------------------
Yeah, I tried the "Finally" block before, but I came to the conclusion that
the Finally block never got hit if there had been an exception caught anyway
(am I wrong?) - therefore I plonked it in both...to be honest I use this in
so many places it should probably become another function that I call in
these places anyway instead of duplicating it all the time, and then just
handle any "other" items that need tidying up in each specific area.

The code in the Finally block always runs, exception or not.
Erm - not quite :eek:)

How is it the same? It looks like you try to use an existing connection and
open it - in mine I'm looking to see if there is a connection object that
isn't nothing - and if there is, try to close it, and then kill it
off...I've probably misunderstood feel free to enlighten me :eek:)

I'm creating a new connection, then opening it. The Using just
automatically adds a Finally and calls close() on the connection. Maybe
I shouldn't have brought it up. It's just a shorthand syntax and you
can get the same results without it.

I'm trying to find a decent article on this, but I haven't found
anything yet.
Thanks again for your reply.

No problem. I just hope I make sense and am not confusing things further.
 
S

Steve C. Orr [MVP, MCSD]

I always test for a null return values from functions unless I'm 100% sure
they'll never return a null, because often times they do.
The only real standard is to throw an exception if the data layer was unable
to retrieve the data. Of course there are reasons to sometimes go for
alternate designs, but that's purely up to you. The important thing is that
you document your public interfaces and list all possible return values and
the exceptions that could be thrown.
 
R

Rob Meade

..

[snip]
No problem. I just hope I make sense and am not confusing things further.

Hi David,

Many thanks for the informative reply, and nope - I'm with you so far - what
was nice to see was that you have got a class for the return object, I think
(although cant remember now, and am too lazy to check) that I queried this
in the initial post - ie, is that the way to go - presumably, if the return
class returns an "object" rather than a specific type it should be able to
be used against any of my custom classes?

Thanks again

Rob
 
R

Rob Meade

...
The important thing is that you document your public interfaces and list
all possible return values and the exceptions that could be thrown.

ROTFL! You've clearly never worked in the NHS! :eek:D Documentation you say -
lol!

The amount of times I've banged on about this in our team - the
documentation we do have is really old for stuff that was written ages ago
when our team was considerably less busy...it'll bite us in the ass I know
for sure - and joking aside thanks for the reply and info about the
functions...

Documentation - *chuckle* :eek:D

Rob
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top