Here’s the code example :
Try
Throw New FirstException()
Finally
Throw New SecondException()
End Try
I figured out it only throws SecondException out and FirstException just vanishes.
I thought FirstException would be inside InnerException property of SecondException but it appears it is not.
I’m not blocked on anything as I don’t really need the FirstException to show up, I’m just rather intrigued about this behaviour.
-
Is there a way to know SecondException did get thrown first when
catching it all at upper level ? -
If the first exception really is overriden by the second, what is the
reason ? -
Does it happen in every other language ? Is it logical ?
One of the limitations of exception handling in .net is that there is no nice way for code in a
Finallyblock to know what exception, if any, caused the code in theTryblock to exit, nor is there any normal way for code in a finally block which does have such information to make it available to code which might throw an exception.In vb.net, it’s possible to kludge things in a manner that works pretty well, even though it looks a bit ugly.
The module above starts with a couple helper modules which should probably be in their own “Exception helpers” module. The ExceptionTest method shows the pattern for code which might throw an exception in both the
TryandFinallyblock. The ExceptionTest2 method calls ExceptionTest and reports what exception if any comes back from it. ExceptionDemo calls ExceptionTest2 in such a way as to cause exceptions in different combinations of theTryandFinallyblocks.As shown, if an exception occurs during cleanup, that exception will be returned to the caller, with the original exception being an item in its
Datadictionary. An alternative pattern would be to catch the exception that occurs on cleanup and include it in the data of the original exception (which would be left uncaught). My general inclination is that it’s probably better in many cases to propagate the exception that occurs during cleanup, since any code which was planning to deal with the original exception will probably expect that cleanup succeeded; if such an expectation cannot be met, the exception that escapes should probably not be the one the caller was expecting. Note also that the latter approach would require a slightly different method of adding information to the original exception, since an exception which is thrown in a nestedTryblock might need to hold information about multiple exceptions that were thrown in nestedFinallyblocks.