Be careful with filtered Exceptions

While researching a good exception handling strategy for the company I work for, I came across an interesting issue with filtered exceptions.

For those who may not know, managed extensions for C++ and VB.NET expose .NET's ability to do filtered exceptions (C# does not allow this). A filtered exception is basically "only catch this exception under certain circumstances". Here's a silly example:

Try
    DoSomething()
Catch ex1 As ArgumentException When someVar = 19
    ' blah, blah, blah
Catch ex2 As Exception when someVar < 5
    ' blah, blah
Finally
    ' more blah
End Try

The expression of the "When" clause can be anything -- including a function call:

Catch e As LowBalanceException When GracePeriodIsOver()

As a quick review of how exceptions are caught and processed, here's a recap from the .NET SDK docs:

When an exception occurs, the system searches for the nearest catch clause that can handle the exception, as determined by the run-time type of the exception. First, the current method is searched for a lexically enclosing try statement, and the associated catch clauses of the try statement are considered in order. If that fails, the method that called the current method is searched for a lexically enclosing try statement that encloses the point of the call to the current method. This search continues until a catch clause is found that can handle the current exception, by naming an exception class that is of the same class, or a base class, of the run-time type of the exception being thrown. A catch clause that doesn't name an exception class can handle any exception.

Of course, we can't forget the finally clause that allows us "clean things up":

Once a matching catch clause is found, the system prepares to transfer control to the first statement of the catch clause. Before execution of the catch clause begins, the system first executes, in order, any finally clauses that were associated with try statements more nested that than the one that caught the exception.

To make things interesting, let's repeat one part of the "try" documentation from above:

...the associated catch clauses of the try statement are considered in order

What this means, is that you can have code execute outside of the try/catch/finally block before the finally block is executed. In the example I showed above, if .NET was looking for a matching catch clause on an exception and found the "When GracePeriodIsOver()" clause, it would have to run that method before determining if the catch block should, in fact, process the exception. The .NET docs covers this under "Securing Exception Handling". Why is it placed under that heading? Because of this:

Try
    IncreasePermissions()
    ' do stuff
Catch ex As Exception When CheckDates()
    ' stuff
Catch ex As Exception When CheckTimes()
    ' more stuff
Finally
    RestorePermissions()
End Try

In the code above, the CheckDates() and CheckTimes() functions will be running under increased permissions! Here's the link to the documentation that prompted me to blog about this. An interesting side-effect of filtered exceptions I never really thought about.

No Comments