Try Catch question

W

Woody Splawn

I have a try catch statement in a fucntion that is supposed to return a true
or a false

My code looks like this:

Try
mySqlConnection.Open()
Dim Da1 As New SqlDataAdapter("Select JnlType, Description from
JnlType", mySqlConnection)
Dim Ds As New DataSet("X")
Da1.Fill(Ds)
Catch
MsgBox("There was a problem filling the Dataset for Lookup table
for JnlType")
Return False
Finally
If mySqlConnection.State = ConnectionState.Open Then
mySqlConnection.Close()
End If
End Try

My question is this: Is the Try Catch code smart enough to run the Finally
statment after the MsgBox and then return false or do I need to write the
code some other way. This is what I want it to do but I am not sure I have
it written correctly.
 
W

William Ryan eMVP

Finally will always be executed and yes, it will still return false the way
you wrote it.
 
T

Tom Leylan

William... I believe we need to clarify something. It isn't going to
return FALSE because of the way he wrote it. It is going to return FALSE
because it ends up FALSE when no return value has been set.


Woody... I don't think you want it to just "accidentally" work. Test it
yourself but (as part of the test) have a function return an integer so you
can get more than 2 return values.

Unless I'm greatly mistaken it works as follows:

You want two return statements in your code: Return True in the Try block
and Return False after the End Try. With no return in Catch or Finally.

If there is no error it will return the value in the Try block (TRUE) if
there is an error the Catch block executes, the the Finally and you will
return the value of the Return statement (FALSE).

Interestingly even if you place a return statement in the Catch block it
will not be returned. Either the Try return works or the final return does.

Test it out...
Tom
 
W

William Ryan eMVP

Tom:

Good call, and yes you're absolutely correct. I realize my answer may have
been misleading -- I was answering it in the context of if an exception was
caused b/c it seemed he was asking about the behavior of Finally. However,
if you don't return a value in this instance, it will in fact return false.
That's more a function of how VB.NET can allow you to not explicitly return
a value in a function but you have a good point nonetheless.

I'll be more clear next time.

bill
 
B

Brian

Woody, you wrote it correctly. It will return False because all the code in
your catch block will run. It doesn't matter if you have a Finally or not. I
wouldn't change a thing. It works perfectly.
 
B

Brian

Oops, I would change one thing: Put a Return True after Da1.Fill(Ds). Then
it should work correctly.

Try
mySqlConnection.Open()
Dim Da1 As New SqlDataAdapter("Select JnlType, Description from
JnlType", mySqlConnection)
Dim Ds As New DataSet("X")
Da1.Fill(Ds)
Return True <-------------------ADD THIS
Catch
MsgBox("There was a problem filling the Dataset for Lookup table
for JnlType")
Return False
Finally
If mySqlConnection.State = ConnectionState.Open Then
mySqlConnection.Close()
End If
End Try
 
T

Tom Leylan

Test it Brian... your I believe you will find that your Return False doesn't
execute.
 
B

Brian

I did. It worked perfectly. Now it's your turn to test it. Use the debugger
to step thru the code.

Private Function Test() As Boolean
Dim g As Integer = 5
Try
g \= 0 '<----------Force an exception , will return false.
Then change it to g \= 1 will return True
Return True
Catch ex As Exception
MessageBox.Show("Caught")
Return False
Finally
MessageBox.Show("Finally")
End Try

End Function
 
T

Tom Leylan

Seriously I wouldn't have mentioned you trying it if I hadn't :) I didn't
step through it with the debugger but I did set return values. This time
however it is returning the return value in the catch block... I mentioned
in another reply that it didn't matter. Can't imagine what I did
differently.

Let me post my code and Woody can decide what he prefers. While it works as
you posted it something seems odd about "return" which is supposed to exit
immediately suddenly not exiting. Clearly the error handler has deferred it
but perhaps that is why Woody was uncertain. What I've done is simply use
the Function name which as we know will return the value and does not cause
an immediate exit (in the normal case) so it behaves identically whether or
not an error has occurred.

You are correct however that it works fine the way you posted it. I don't
know what I did in my first test...
Tom


Public Function ErrorSub() As Boolean

Try
Throw New System.Exception("error")
ErrorSub = True

Catch ex As Exception
MsgBox("catch", MsgBoxStyle.OKOnly, "error")
ErrorSub = False

Finally
MsgBox("finally", MsgBoxStyle.OKOnly, "error")

End Try

End Function
 
T

Tom Leylan

Turns out it wasn't such a good call. I swear I tested the code but
"something" mixed me up.

The Return statement is deferred until after the finally statement
executes... the line is executed but it doesn't actually exit at that point.
So anyway, it would work but I posted slightly different syntax (using the
function name) which makes it clearer (to me) that it is only assigning the
value and can't possibly return at that point.

Tom
 
W

William Ryan eMVP

Tom:

Your point is still correct, namely that if you don't specify a return type
in your function, it's coming back null. If you look at the original
question and context, it will return false if an exception is thrown.
VB.NET is 'smart' enough to fire the messagebox, return false and execute
the code in the finally statement.

I guess another point worth bringing up is that Finally blocks aren't well
suited to returning values in many cases if you plan on having a specific
return value if an exception(s) is/are raised. Finally clauses lend
themselves quite well to cleanup code, streams, connections and the like,
but return values aren't really well suited to it. Every MCAD test guide
I've seen raises this issue ;-).
 
P

Peter Huang

Hi Woody,

Thanks for posting in the community.

First of all, I would like to confirm my understanding of your issue.
From your description, I understand that you are confused by the
Try...Catch...Finally...End Try Block.
Have I fully understood you? If there is anything I misunderstood, please
feel free to let me know.

I think in the Try...Catch...Finally...End Try statement, if there is
Exceptionin the Try and The Exception was catched by Catch statement, the
Catch statement will be run.
And the Finally block will be called whether there is Exception in the Try
or not.

Here is my demo code you may run it to see if this will help you to
understand the Structured Exception Handling.
Module Module3
Public Function Func(ByVal isEx As Boolean) As Boolean
Try
Console.WriteLine("Try Block")
If isEx Then
Throw New Exception("Throw Error")
End If
Return True
Catch ex As Exception
Console.WriteLine("Catch Block:" + ex.Message)
Return False
Finally
Console.WriteLine("Finally Block")
End Try
Console.WriteLine("This line of code will not be run")
End Function
Public Sub Main()
Console.WriteLine(Func(True))
Console.WriteLine()
Console.WriteLine(Func(False))
End Sub
End Module

Also you may take a look at the link below,
Walkthrough: Structured Exception Handling
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbcn7/html/
vawlkWalkthroughStructuredExceptionHandling.asp


Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 
C

Cor

Hi Woody, Tom, Bill

I do it totaly different from the rest and I think this is the best way (for
a dataadapter)

:))

\\\
Try
Dim Da1 As New SqlDataAdapter _
("Select JnlType, Description from JnlType",
mySqlConnection)
Dim Ds As New DataSet("X")
Da1.Fill(Ds)
Catch sqlExc As SqlException
MessageBox.Show(sqlExc.ToString)
Return False
Catch ex As Exception
MessageBox.Show(ex.Message)
Return False
Finally
mySqlConnection.Close()
End Try
Return True ' Tom, I would have forgotten this if I had not looked at your
message.
///
 
C

Cor

Hi

A correction Jon pointed me on.

And than it becomes in my opinon.
\\\with a single datatable to fill
Try
Dim Da1 As New SqlDataAdapter _
("Select JnlType, Description from JnlType",
mySqlConnection)
Dim Ds As New DataSet("X")
Da1.Fill(Ds)
Catch sqlExc As SqlException
MessageBox.Show(sqlExc.ToString)
Return False
Catch ex As Exception
MessageBox.Show(ex.Message)
Return False
End Try
Return true
///
Or with a multiple datatable to fill
\\\
Try
mySQLConnection.open
Try
Dim Da1 As New SqlDataAdapter _
("Select JnlType, Description from JnlType",
mySqlConnection)
Dim Ds As New DataSet("X")
Da1.Fill(Ds,"Table1")
dim da.command = ("Select JnlType, Description from
JnlType2")
Da1.Fill(Ds,"Table2")
Catch sqlExc As SqlException
MessageBox.Show(sqlExc.ToString)
Return False
Catch ex As Exception
MessageBox.Show(ex.Message)
Return False
End Try
Catch ex As Exception
MessageBox.Show(ex.Message)
Return False
Finally
mySQLConnection.close
End Try
Return true
///
 

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

Top