Exceptions: Don’t bite off more than you can chew!

Many modern programming languages feature some form of exception handling facility, and although I am going to be talking particularly about C# in this post, it can probably be applied to any language that has exception handling.  Exception handling is very useful for the graceful handling of unexpected errors (exceptions) during program execution, however there are a few gotchas to be aware of when using exception handling.

Possibly one of the most important practices in the effective use of exceptions is to only catch the exceptions you are expecting and that you can handle safely, however a very common mistake when starting to use exceptions is to catch (and possibly suppress) every exception. For example:

try
{
// some code that throws exceptions occasionally
}catch{}

In the above example the programmer has discovered that their initial code is occasionally throwing exceptions, so they have enclosed the offending block of code in a try/catch block.  The use of a try/catch block means that any exceptions that occur inside the try clause are caught by the catch clause, this prevents the program from crashing due to unhanded exceptions.  However, the use of an empty catch clause means that any exception that is thrown will be caught by the catch clause.  The drawback to this is that the catch clause is empty, which means that every exception caught effectively disappears, which makes debugging and diagnosing abnormal program behavior incredibly hard, as that empty catch clause is effectively an exception black hole destroying any evidence.  This form of ‘exception handling’ is worse in my opinion than no exception handling: though it may prevent the program crashing due to unhandled exceptions it makes debugging the program exceptionally hard. The following snippet is an improvement:

try
{
// some code that throws exceptions occasionally
}
catch( Exception e )
{
// some exception handling
}

The above snippet is a distinct improvement on the previous snippet as the catch clause now catches exceptions and attempts to perform some form of exception recovery or logging. This is a lot better as at least some form of corrective action is taking place.  Yet there is still a drawback: the catch clause is still catching every exception that is thrown by the try block. This means that even the abnormal exception types the programmer does not expect are being caught.  The following is a better snippet:

try
{
// some code that throws exceptions occasionally
}
catch( System.ArgumentException e )
{
// some specific exception handling
}

In this example the programmer is now only catching the exceptions they expect their code to throw, which means that unexpected and abnormal exceptions are not caught. This is an improvement, as these unexpected exceptions will now filter up the call stack to more appropriate exception handlers and eventually to the try/catch clause in the main function of the application.  This means that when something truly rare and weird happens, e.g. an underlying system breaks causing an unexpected exception, that the truly exceptional exception is not caught by the original try/catch block but filters up to higher level exception handlers which hopefully alert the user (or at least the investigating programmer) that a truly exceptional event has occurred.

try
{
// some code that throws exceptions occasionally
}
catch( System.ArgumentException e )
{
// some specific exception handling
}
catch( Exception e )
{
// generic exception handling
}

In this last example specific exceptions are caught by the first catch clause which catches only the exceptions the programmer is expecting and then a second catch clause catches all the other exceptions the programmer did not expect. This form of exception handling is good if there is no general exception handler further up the call stack to catch the unexpected exceptions e.g. in a library. In summary exception handling is a very useful tool but you need todevelop the habit of catching exceptions responsibly and to not catch exceptions you don’t intend to handle.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>