Microsoft’s best practices regarding error handling are pretty clear. They are designed to avoid losing information that might be helpful to the developer, to provide a reasonable user experience, and to prevent a huge performance hit every time something goes wrong.
So, you’ve got your exception handlers all in a neat row, following best practices. In the inevitable event that something goes wrong, your application will properly handle the exception at one level or another.
Or will it? What about exceptions that happen outside your code? The obvious answer is an unhandled exception handler, but writing those can be tricky work, as any problems there will bring your application to a screeching halt.
And, once you have the exception in some sort of handler, then what? You clearly don’t want your carefully crafted error information to simply fall into a bit bucket. Relying on the user to tell you the exception call stack is not a good idea.
Instead of re-creating something that has been written countless times, I decided to look around to see what’s already been done. Like many enterprise, system, or application aspects, error handling and reporting does fairly common things, regardless of the purpose of the software in question. In a search for something else, I came across Jeff Atwood’s blog  entry for exception handling.
Atwood’s example is in VB. A majority of my work is in C#, so while I was reviewing the code, I translated it into C#. I also came up with a number of improvements to add to it:
- Instead of configuring which destination(s) to log errors, I added a fallback algorithm. Logging to the database gets priority, but if that fails, the local event log is a backup. If that fails, then saving to a local file is a last resort. The error is always sent via email.
- The separate web form and Windows form libraries are easily combined. I’ve also rolled it into a library of common utilities, providing all the extra features I often look for in a single project. Moving the common methods into a common base class helps with maintenance.
- Some of the internal fallback exception handlers were not very helpful in documenting the secondary error, and event handling results were not always well handled. I tweaked both to provide a little more information.
- The pretty call stack formatting was showing parameters in VB format. To be consistent, I changed it to C# syntax.
- SMTP email handling classes were added to the framework in version 2.0. I replaced the use of the hand-crafted classes with the framework classes. I also looked up the settings to use Gmail to send the alerts. This can be very handy when initially setting up an application and your client doesn’t have their servers up and running, yet.
- There are times when the application can handle the exception, but you want the problem logged for later analysis. I added an overload that allows error handling and logging without interrupting the user or halting the application.
Integration with enterprise aspects is simple enough. In fact, having a framework for configuration, logging, and database access makes logging to the database quite easy.
Using the code
The solution provided includes four projects. Three of those are examples of use in console, web, and Windows Forms applications. The fourth is the error handler library itself.
The key for the console and Windows Forms applications is the registration of the unhandled exception event delegate. This is handled in a simple method call:
ErrorHandler.ExceptionHandler.AddHandler( true, true, true );
The parameters determine the default behavior for unhandled exceptions.
- MSDN: Best Practices for Handling Exceptions
- The original articles can be found under Jeff Atwood's postings - User Friendly Exception Handling