Dallas, June 6, 2003 – Today was the last day of TechEd 2003. There were still a number of interesting presentations. Subjects that apply both to desktop and device developments on an architectural level are covered by the Patterns & Practises Team at Microsoft. One of the interesting and yet controversial topics is Structured Exception Handling (SEH). Ron Jacobs, program manager of the team had an entire presentation covering SEH. According to him, exceptions are one of the most exciting topics in the world. First let’s ask ourselves what an exception really is. The definition is simple: “An exception is an unexpected error condition or unexpected behavior”. The key element in the definition is the word unexpected. Exceptions can be raised because of a fault in your own code or in the code you call. Examples are unavailable operating system resources or unexpected conditions that the Common Language Runtime (CLR) encounters. Applications can recover from some of these conditions, like file not found exceptions or database timeouts, but not from others, like out of memory exceptions. Structured Exception Handling offers several advantages over traditional error handling mechanisms:
- Return values might be ignored, exceptions can not be ignored
- Invalid values do not continue to propagate through the system
- It is not necessary to check for return values
- Exceptions are easy to add to increase program reliability.
It is important to think ahead how to deal with exceptions. That is what exception management covers. Exception management defines a way to deal with exceptions like detecting them, logging and reporting exception information or fire events. Exceptions happen when we least expect them so we have to plan ahead for them. It is very important to test your exception strategy, so it is necessary during test runs to inject faults in a system. When an exception is not detected by your own application it will go up in the calling stack. Eventually unhandled exceptions will reach the boundaries of the system. In that case the CLR will do ugly things on your behalf like closing down the application. The controversy with SEH has to do with performance issues. Exceptions are rather expensive, but since they should be exceptional there is no a reason to be afraid of this. Think of exceptions as a last resort to maybe escape from a nasty situation. All .NET languages have built in SEH. The first question that comes up is when to catch exceptions. A very generic answer is that exceptions should probably not be caught at the lower levels of your software. Only if an exception needs more clarification for debugging information or when it is possible to recover from an exception it should be caught. The next question is when to throw exceptions. Again, a general answer is that it is wise to throw an exception is conditions outside your own code’s assumption occur, for instance we assume that a database is up and running but it is not. Exceptions should not be used for intended functionality to go wrong, like handling invalid user passwords.

Figure 1: The wrong way to open a file causes an exception and application termination.
Consider the following example. We have an application that wants to open a file to read data from it. Figure 1 shows the wrong way to deal with this. We try to open a file but don’t test if opening actually was successful, so the system threw an exception, but our application code ignored it. This is a situation where terminating the application was not necessary.

Instead we could have caught the exception and give the user a friendlier error message after which the user could retry.

The code for this behavior is somewhat more complicated because we are handling a particular exception right now.

The “magic” occurs in the catch block. By dealing with the FileNotFoundException in our code we are able to pass a friendly message to the user and to continue executing. There are quite a few exceptions available. Another exception is for instance the ArgumentException. This would have been thrown if a method would receive wrong parameters. In our example this would have happened if we would have passed an empty string to the StreamReader. Since this is an exception that would be thrown on intended functionality (a user hits the open button by accident) we don’t allow the system to throw an exception but handle the error beforehand in our own code. The difference is the fact that our application knows that an empty string is definitely an invalid filename, but it can’t know if any non empty string is a valid filename. Therefore, as long as a filename has been entered by the user we let the system determine if it is a valid filename. Of course this is not a thorough and in-depth description of exception handling, but at least you should get some ideas of what it is all about. |