Over the past year or so ELMAH has becoming increasingly popular, and it’s not hard to see why. It has an excellent set of error logging and reporting features, doesn’t need to be referenced directly in any application code and is simple to configure.
Recently a troublesome ASP .NET application came into my care and I decided the first course of action was to plug ELMAH in. At the most basic level, this involves dropping the ELMAH dll into bin and a few changes to web.config; Scott Hanselman shows you how to do this on his blog.
However, because the app was built using ASP .NET MVC, its default HandleError attribute was intercepting all exceptions thrown by controllers, before ELMAH could got a look at them. As a result not all exceptions were being logged. To counter this, I created a custom version of the HandleError attribute, called ElmahHandleErrorAttribute. Well actually, Atif Aziz, author of ELMAH did, in a post on Stack Overflow, I just copied it!
The last piece of the puzzle is to create a base controller, from which all controllers in the application inherit, and apply the ElmahHandleErrorAttribute to it. Now all exceptions in the application will pass through the ELMAH pipleine.
It’s important to test that any custom error pages are also shown after ELMAH has done its bit. To do so, switch customErrors in web.config to on so that those pages are shown in preference to the traditional yellow screen of death (more information on customErrors can be found at MSDN). If you have error pages specific to particular HTTP error codes (i.e. one for 404s and one for the rest) then add these now.
Next, do something that is guaranteed to throw an exception in the app. Most of the time a typo in the connection string, if using a database, is a simple but effective way of doing this. Afterwards, ELMAH will have logged the exception (go to /elmah.axd to check) and the friendly error page will be rendered.
The reason I suggest testing these pages is that when developing locally, most of us run with customErrors off so we get the YSOD in all its glory, stack trace and all – and so we should. As a result, if there are any issues with custom error pages not being shown correctly, they often only come out during formal testing, at which point it is often more time consuming to fix.
I’ve tripped over this myself a couple of times, particularly if the custom error page accesses the database. Imagine a situation in which the database is offline, and an exception is thrown. ELMAH logs the details, and ASP .NET MVC tries to render the custom error page, at which point another attempt is made to connect to the database! The custom error page will then blow up – not good at all.
The lesson here is that custom error pages should be as basic as possible. If they use the same master page as the rest of the app, and that master page shows a database value somewhere in the header or footer (e.g. friendly name of the current user, which is quite common), they are vulnerable to this problem. Far better to have a separate master page for all error pages which uses the same styles as the rest of the site but consists of plain, basic markup.
One last point to make is that ELMAH isn’t just for web apps, although it works best there. I recently worked on a solution that had a web front end and a console application for pumping data into the database. I made use of ELMAH in both apps, thereby having a central repository for all exception information. I’ve pointed my feed reader at ELMAH’s RSS feed (/elmah.axd/rss) and am notified as soon as any part of the solution experiences an error.
So, if you’re not yet on board the ELMAH bandwagon, now is the time to join in