Try Catch Else Finally

C

cj

Another wish of mine. I wish there was a way in the Try Catch structure
to say if there wasn't an error to do something. Like an else
statement. Try Catch Else Finally.

Also because I understand Finally runs whether an error was caught or
not, I haven't found a use for finally yet.
 
M

Marina Levit [MVP]

That's what the Try is for. To do stuff with the assumption that there are
no errors. The catch is to deal with any errors. And the finally is to run
regardless of whether or not there were errors.
 
A

AlanT

Not too sure if I understand the question.

The mainline of the Try block is the implied 'do this if no error'
branch, with the the catch occuring only if an exception occurs.

Do you have an example of the functionality that you would like to see.


As for the finally

One example is to close files

e.g.

Dim fs As FileStream
Dim reader As TextReader

Try

fs = New FileStream("test.txt", FileMode.Open)
reader = New StreamReader(fs)

While True

Dim str As String = reader.ReadLine
If (str Is Nothing) Then
Exit While
End If

Trace.WriteLine(str)

End While

Finally

If Not fs Is Nothing Then
fs.Close()
End If

End Try

Say something went wrong during a read (or if we we doing something
more complicated with the input than just dumping it to trace) then
when we the exception occurs we want the filestream to be closed. We
also want it to be closed during the normal flow.


hth,
Alan
 
C

cj

So are you saying if I have that if line 2 throws and exception it will
skip 3, 4 and 5 and go straight to catch?

If so, the next question is how do I know it was line 2 that threw the
exception and not line 1 or 4?

try
1
2
3
4
5
catch
a
end try
 
M

Marina Levit [MVP]

Yes, that is what I am saying. That is the whole point of a try block.

You wouldn't know which one it was. You would need a separate try/catch for
each line of code if you had different error handling code depending on
which exact one threw the exception.
Or if the different things threw different types of exceptions, you could
have multiple catch blocks each catching a different exception type, and
have different error handling code execute that way.
 
C

cj

Your right Marina Levit has already set me straight. Only remaining
downside is I wouldn't know which line caused the exception. Thanks for
the reply.
 
C

cj

Thanks, I really didn't know or at least think about doing it that way.
I knew several lines could be in try but I guess I was still thinking
I needed to check soon to see if a particular line had an exception. I
guess I still do but I guess I can have nested try blocks. That'd
probably take care of my issues. Thanks!
 
C

cj

If I call a sub as one of the inside within a try, would the try trap
errors in the sub? I hope not. My intention is only that this sub
should only be run if there were no errors in the statement before it.

Also I'm not sure I understand Finally. How are statements in finally
different from those that follow the end try?
 
M

Marina Levit [MVP]

I don't really follow what you are saying here.

I would re-evaluate if you really need different error handling logic for
every statement. Nested try/catch blocks look pretty ugly and are hard to
follow.

The finally statements are different because they execute after the Try if
no errors happened. They also execute if there was an error and a catch was
run. The Finally block is guaranteed to execute regardless of whether or not
an error occurred in the Try.

I recommend you read up on try/catch/finally blocks in the documentation and
take a look at some samples. That might help you figure out the right way of
using it.
 
J

Jim Wooley

Your right Marina Levit has already set me straight. Only remaining
downside is I wouldn't know which line caused the exception. Thanks
for the reply.

You CAN get the line that caused the exception if you number your lines (like
old Basic). The following is perfectly acceptable VB.Net code:

10: REM This program doesn't do much
20: Try
30: REM Throw an error
40: Throw New DivideByZeroException
50: Catch ex As DivideByZeroException
60: Console.WriteLine("Error occured in line: " & Erl())
70: End Try
80: Console.ReadLine()

The output is:

Error occured in line: 40

The upside is: the line numbers are retained when you compile in release
mode. The down side is that there is a performance hit, so you would only
want to do this when it is essential you know the line causing the problem
and speed is not as important.

Jim Wooley
http://devauthority.com/blogs/jwooley/archive/2005/12/21/661.asp
 
A

AlanT

The stack trace from the exception will show you where the exception
occurred.

hth,
Alan.
 
C

cj

My cut and paste typing was pretty bad wasn't it. Let me try again.

I have this now. The IF that checks to see if I got back session
dropped should not execute if respstr=proxy.validate failed. Here I
ensure that by checking to see if respstr=""

Try
respstr = proxy.validate(soapmesg)
Catch ex As Exception
procLabel2.Text = Now() & " Error executing Validation request"
procLabel3.Text = ex.Message
respstr = ""
End Try

If Not respstr = "" And respstr.Substring(0, 28) = _
"Session Dropped, Login Again" Then
loginABC(Me, Nothing)
End If

Suppose I did this instead:

Try
respstr = proxy.validate(soapmesg)
If respstr.Substring(0, 28) = "Session Dropped, Login Again" Then
loginABC(Me, Nothing)
End If
Catch ex As Exception
procLabel2.Text = Now() & " Error executing Validation request"
procLabel3.Text = ex.Message
End Try

Is it possible the catch would catch and error that occured in loginABC?
I hope not.
 
C

Cor Ligthert [MVP]

CJ,

The statements in the finally block will be always executed unless you power
your computer down before that or execute the End statement. (Even if there
is a return in the sub than the finally will be done first).

I hope this helps,

Cor
 
C

Cerebrus

Hi,

Is there something I'm missing here, Jim ? Why go to such an extent
when the line no. can be determined easily. If I simply include the
following line within my Catch block :

:
:
Catch ex as Exception
Console.WriteLine("ex.ToString()")
Finally...


I can get the output which gives the Line no. at which the error
occurred. This is because using ToString() here appends the Message
Property and the StackTrace property (which contains the Line no.) and
displays it as a string.

So, why should we have to add in Line nos. manually to the code ?

Regards,

Cerebrus.
 
C

cj

I guess I'll have to do some reading on finally. I'm still not sure I
see the use. Perhaps it's how I'm using try catch. My purpose in using
try catch is that without it, or some other error handling, if a command
throws an exception the program halts with some garbage on the screen.
I've written my program with try catch around statements like calls to
other servers where something like a cable being cut might cause the
line to throw and exception as it can not execute. In the catch I want
to know what command is giving the problem. That'll help me know what
is wrong. I print a custom message to indicate what code is being
executed and the ex.message info to the screen for diagnosis. I need to
know which stored procedure will not work, or is it the request to the
remote server or did it try to parse the xml file and find out it wasn't
a xml file? The presence of an error like this can mean skip the
current record or it might mean reattempt the failed command until it
starts working.

In any event after the try catch the program continues to run. I test a
flag variable or some other way to see if the previous statement threw
an exception and make my processing decisions based on that. So my code
after the try catch always executes--how is that different from being in
finally?
 
C

cj

My guess would be he assumes, and I expect I would if I used this
approach, make a decision on what to do in the catch based on the line
number catch tells me the error occurred on. So I need at coding time
to see what line is what number to program in specific actions to be
taken for specific lines.

Sorry Jim, line numbers are on thing I don't want to bring back.
 
C

Charles Law

Hi CJ

Here is an example

<code>
Sub Button1_Click(...) Handles ...

Try
DoFileStuff

Catch ex As Exception
' This is a catch-all because we don't want
' our button click handler to blow up
MessageBox.Show(ex.Message)

End Try

End Sub

Sub DoFileStuff()

Try
OpenFile

WriteToFile

Catch ex As SpecificException
' Catch this exception because we know what to do if it occurs

Catch ex As SomeOtherExceptionThatICanHandle
' Catch this exception as well for the same reason. However
' it requires a different reaction, so we catch it separately

Finally
' This will always execute, even if UnexpectedException is thrown
If FileIsOpen Then
CloseFile
End If

End Try

' Code here will not execute if UnexpectedException is thrown,
' so we cannot rely on closing the file here

End Sub
</code>

HTH

Charles
 
P

Patrice

It could be also because he tries to catch global errors instead of having
multiple catch clauses. IMO he's best bet for now would be to give a close
look at the Try statement...
 
M

Marina Levit [MVP]

You can get line numbers, but that is only good for showing error messages.
It's not like you can in code figure out which function call caused the
error - unless you start hard coding if statements to look for specific line
numbers - but that isn't something you would ever want to do.

cj wanted to figure out which line of code was causing the problem, to
presumably either have different error handling code, or ignore the error,
etc. That isn't something the stack trace information can realistically help
with.

Not to mention, line numbers come up only when compiled in debug mode.
 
C

cj

I see a couple things here.

1. is the button1_click catch catching exceptions thrown by lines
inside dofilestuff or just if the line dofilestuff itself for some
reason threw an exception?

2. your catching different types of exceptions. I'm catching any
exceptions and treating them all the same. The show must go on in my
program regardless of any exceptions. Some lines an exception on them
would be best handled by retrying the line and others by skipping to the
next iteration of the program. ie on reading from a server it'd be best
to retry untill it works while on getting a badly formated xml file from
the server I'd probably flag that transaction as questionable and try
the next request.
 

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