VB.Net 2005 - Question on Nested Try Catch Finally

dlabar

New member
Joined
Aug 17, 2007
Messages
4
Programming Experience
1-3
I am trying to update data that is linked in two different databases. If the attempt to save the data in database 1 fails, I need to do some cleanup in database 2 and E-mail that the error occured. This results in something like this:



VB.NET:
data = GetDataToSave()
Try
    SaveDataInDatabase1(data)
Catch exOuter as Exception
    CleanupDataInDatabase2()
    EmailAndWriteErrorToLog("Save data in database 1 failed!", exOuter)
    Throw
End Try

But if the CleanupDataInDatabase2 Sub fails, the email and throw statements will never get executed. So that results in something like this:

VB.NET:
data = GetDataToSave()
Try
    SaveDataInDatabase1(data)
Catch exOuter as Exception
    Try
        CleanupDataInDatabase2()
    Catch exInner as Exception
        Try
            EmailAndWriteErrorToLog("Cleanup Data in Database 2 failed!", exInner)
        Catch ex as Exception
            'Unable to e-mail error, Nothing else to do.
        End Try
        
        Throw New Exception(exOuter.toString(), exInner)
    Finally
        Try
            EmailAndWriteErrorToLog("Save data in database 1 failed!", exOuter)
        Catch ex as Exception
            'Unable to e-mail error, Nothing else to do.
        End Try
    End Try
 
    Throw
End Try

I want to call the sub CleanupDataInDatabase before e-mailing the error for the Save Data in Database Failed because the computer could possibly die when sending the e-mail before it cleans up the database.
Anyone have a better idea for how to handle this?


Is there a better way to create an inner exception than what is below?

VB.NET:
Throw New Exception(exOuter.toString(), exInner)

I used "toString()" because it gives the error message as well as the actual line number and method of the outer exception, rather than "message()".
 
the computer could possibly die when sending the e-mail before it cleans up the database.
Anyone have a better idea for how to handle this?

make the Sub that sends the email safe..
VB.NET:
Public Sub SendErroMail()
  Try
    ''code here to send mail
  Catch Exception
    ''maybe write to the event log here? or something else that is safe!
  End Try
End Sub

even if it fails, it wont affect program flow


Is there a better way to create an inner exception than what is below?

VB.NET:
Throw New Exception(exOuter.toString(), exInner)

I used "toString()" because it gives the error message as well as the actual line number and method of the outer exception, rather than "message()".

i dont generally use inner and outer exceptions, i just look at the type of the exception. You should note that while tostring might have a line number now in a debug environment, I dont think it will have in a production envronment, so if youre relying on it.. dont.
 
make the Sub that sends the email safe..
VB.NET:
Public Sub SendErroMail()
  Try
    ''code here to send mail
  Catch Exception
    ''maybe write to the event log here? or something else that is safe!
  End Try
End Sub

even if it fails, it wont affect program flow

There is no actual SendErrorMail() sub. I just simplified the error handling process to show that it wouldn't throw any errors for the purpose of the post.


i dont generally use inner and outer exceptions, i just look at the type of the exception. You should note that while tostring might have a line number now in a debug environment, I dont think it will have in a production envronment, so if youre relying on it.. dont.

I understand looking at the exception type, but in this case, two seperate exceptions have taken place, and I want to make sure both get raised. I don't care about the type.
 
There is no actual SendErrorMail() sub. I just simplified the error handling process to show that it wouldn't throw any errors for the purpose of the post.
So.. make it! :)



I understand looking at the exception type, but in this case, two seperate exceptions have taken place, and I want to make sure both get raised. I don't care about the type.
I'm not sure how it's possible to raise two exceptions.. Are you talking about:

VB.NET:
Try
 ...
Catch Exception e1
  Try
  ...
  Catch Exception e2
    'two exceptions here? 
  End Try
End Try

The idea of Catch Exception e1 is that it handles the e1 scenario.. But if you really want to pass e1 and e2 to the calling procedure, then make your own class:

VB.NET:
Class DoubleException
  Inherits Exception

  Public E1 as Exception
  Public E2 as Exception

End Class

THis is just a very basic stub. You can do better becuase you know your design..

VB.NET:
Dim de as DoubleException = Nothing

Try
 ...
Catch Exception e1
  de = New DoubleException
  de.E1 = e1
  Try
  ...
  Catch Exception e2
    de.E2 = e2
    'two exceptions here? 
  End Try
End Try

If de IsNot Nothing Then Throw de
 
I'm not sure how it's possible to raise two exceptions.. Are you talking about:

VB.NET:
Try
 ...
Catch Exception e1
  Try
  ...
  Catch Exception e2
    'two exceptions here? 
  End Try
End Try

The idea of Catch Exception e1 is that it handles the e1 scenario.. But if you really want to pass e1 and e2 to the calling procedure, then make your own class:


I have two exceptions because Save to database 1 causes an exception, and then as a result of that exception I have to clean up the data in database 2, and if that causes an exception, then I have two different exceptions that I want to be notified about. The save to database 1 failed, and hey, the cleanup in database 2 failed, so take care of both of those.

I never thought of creating a double exception class. Isn't that kind of what an inner exception is? I mean if there is an exception handling the exception, is that an inner exception, or just two exceptions, or is the last exception that happens usually the only exception that gets thrown?
 
I have two exceptions because Save to database 1 causes an exception, and then as a result of that exception I have to clean up the data in database 2, and if that causes an exception, then I have two different exceptions that I want to be notified about. The save to database 1 failed, and hey, the cleanup in database 2 failed, so take care of both of those.

I never thought of creating a double exception class. Isn't that kind of what an inner exception is?
Er.. yeah.. but its not quite the same.. an outer exception may wrap an inner exception because the inner exception caused the outer exception. In this case, the db 1 op failed but that didnt necessarily cause the db 2 op to fail..
Semantically, it makes more sense to put both exceptions side by side rather than one inside the other, but ultimately, it will achieve the same result

I mean if there is an exception handling the exception,
Exceptions dont handle exceptions. Catch blocks handle exceptions

is that an inner exception, or just two exceptions,
Inner Exceptions arent used for situations where handling of one exception encountered another exception. They are used in situations where one exception (e.g. FileNotFOundException) is the root cause of another exception (RenameFailedException)
RenameFailed may also fail because of security permission, or in use .. etc

Sometimes we only want to know THAT rename failed
Sometimes we want to know WHY it failed

*RenameFailed is a bogus exception - illustrating a point, not giving accurate code here

or is the last exception that happens usually the only exception that gets thrown?
Only one exception can ever be thrown at once
 
Back
Top