Your official information source from the .NET Web Development and Tools group at Microsoft.
I'm a fan of using ELMAH to track unhandled exceptions in my ASP.NET applications. If you haven't tried ELMAH, you should definitely check it out. There's even an ELMAH NuGet package so it's trivial to install.
Now that I'm getting my feet wet with Web API, I'd like to have any Web API unhandled exceptions be directed to ELMAH as well so that I have a one stop shop for viewing all unhandled exceptions in my application. Without a bit of work though, this won't happen.
ELMAH records unhandled exceptions by tapping into the Application_Error event of ASP.NET applications, but when a Web API endpoint throws an unhandled exception, this event isn't triggered because the exception is intentionally swallowed higher in the Web API call stack. This enables Web API to send a response to the client like "500 - Internal Server Error". If the exception went unhandled, Web API wouldn't send any response to the client.
If you have a Web API that throws an unhandled exception, ELMAH shows:
So how do we catch these unhandled Web API exceptions and route them to ELMAH?
One good option is to use an Exception Filter. If you're familiar with exception filters in MVC, it's the same idea, but instead of implementing System.Web.Mvc.IExceptionFilter, we need to implement System.Web.Http.Filters.IExceptionFilter (note the namespace difference), and creating a derived class from System.Web.Http.Filters.ExceptionFilterAttribute is an easy approach.
In our derived class, we'll simply override the OnException method and make an explicit log call to ELMAH.
Then, we wire-up our custom exception filter globally by adding our filter:
Now when one of our Web API's throws an unhandled exception, ELMAH picks it up.
Hope this helps, Mark
You can also use ELMAH Web API contrib package (nuget.org/.../Elmah.Contrib.WebApi) for this purpose rather than writing an extra handler.
Good to know. Thanks for sharing that Teoman.
Really appreciate your post. It was the most straightforward one on this topic I was able to find. BTW, some may find it useful that in non MVC contexts you can use the following in Application_Start() to register the filter:
I believe this should use Elmah.ErrorSignal.FromCurrentContext().Raise(context.Exception); in order to get the full elmah pipeline such as email notifications
Thanks for posting this, worked great for me.
RE: the first comment, the Elmah.Contrib.WebApi project doesn't seem to work with the current version of WebAPI- potentially because of this unresolved issue:
Hi, May I know if I should use the normal Elmah package or the Elmah.MVC for Web API projects?