Custom Exception Handling

For anyone considering custom exception handling, there is an important distinction to make: Custom exceptions are one thing, and handling exceptions in a customised way is something else.

The phrase “custom exception” usually refers to an exception class which inherits System.Exception or System.ApplicationException, as demonstrated by the Exception Management Application Block (EMAB). It means writing your own Exception framework, from raising the exception with your own constructor (because any additional information you store must be gathered at the time the Exception occurs), through doing something with it (logging, etc.). The bit in italics will become important later on. Most of the time, these custom classes don't handle casting from the conventional types, meaning for example that you lose the ability to do anything with GetLastError() inside the Application_OnError event for example.

“Handling exceptions in a customised way” normally describes what you can do with the standard Exception classes. ASP.NET has some prety nice features, including standard events, the ability to set default error pages in web.config (like a branded 404 page), or a way to generate a customErrors page (also declared in web.config).

My last MSDN article was entitled “Rich Custom Error Handling with ASP.NET” and it was really about handling errors in a customized way. Specifically, it shows how to overcome the limitations of the customErrors feature by going beyond the On/Off/RemoteOnly settings (for those who don't develop your apps at the server console), so developers see detail while end-users see a simple “sorry,” on a page you can customize any way you like. Who sees what is configured by declaring the IP address block where your developers live, in case you were wondering.

While writing that article, I assumed that the custom exception methods like the EMAB still used the conventional events (e.g. Application_OnError), but they don't. Since classes which subclass the built-in Exception classes gather additional information at the time of the exception, they need to be created on purpose (here come the italics again) with your own constructor. And now for the important part (in bold so you don't miss it): Custom Exceptions need to be created inside a This is why the EMAB has a Publish() function. You can think of Publish() as a constructor that simply inits the custom exception object. [1]

    Throw New System.ApplicationException (“This code breaks.”)
Catch (ex as System.ApplicationException)
    Publish(“Code broke, aren't you glad you put it in a try...catch?”, ex)
    ' or perhaps this instead:
    ThrowMyCustomException(“Something bad, right here!”, ex)
End Try

Where does this leave code that breaks in places you didn't have the foresight to contain in a Right back where you started. In those cases, your fancy custom exception methods are for naught. And in the above I'm also assuming the custom object can do someting meaningful with the ex exception passed it, that isn't the case in most code you'll find lying around the web.

The moral? Whatever you do (logging or notification) with custom exceptions, don't forget to do the same for conventional Exceptions. Is this why people wrap entire methods in blocks, or why the Framework was designed so it isn't a significant hit to do so? [2]

The code is calling, until next time.

[1] EMAB's Publish() actually does more (you can build custom subscribers for the Publish event, wherein the EMAB's full power to confuse unwary developers lies), but let's leave it at “Publish() is like a constructor for a custom exception.”

[2] Rhetorical question.


No Comments