Thursday, April 16, 2015

Web API Global Exception Handling Made Easy

Intro

Exception handling can be a bit of a chore. It always ends up looking the same; the familiar try...catch pattern, maybe you log the exception, maybe you rethrow it, yadda yadda. In a Web API you might even throw back a server error 500 response when you encounter an exception.

I know you're all sitting there chanting impatiently, willing me to tell you I can make it better...easier even! You're probably sitting at your desk or staring at your phone, thinking "Peeticus, please save us from the doldrums of routine! Help us!!". Well OK, just this once.Only because I can see the tears of joy brimming in your eyes.

Example

So I've made a simple Web API. It has a single GET method that throws an exception. Here's the code:

using System;
using System.Web.Http;

namespace BlogWebApiExceptionHandling.Controllers
{
    public class HandlingController : ApiController
    {
        public IHttpActionResult Get()
        {
            throw new ApplicationException("hey, an error!");
        }
    }
}

Run this thing and send a request to it with Fiddler. Here's what you get:
HTTP/1.1 500 Internal Server Error
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?YzpcdXNlcnNccGVldGljdXNcZG9jdW1lbnRzXHZpc3VhbCBzdHVkaW8gMjAxM1xQcm9qZWN0c1xCbG9nV2ViQXBpRXhjZXB0aW9uSGFuZGxpbmdcQmxvZ1dlYkFwaUV4Y2VwdGlvbkhhbmRsaW5nXGFwaVxoYW5kbGluZ1w=?=
X-Powered-By: ASP.NET
Date: Fri, 17 Apr 2015 01:20:24 GMT
Content-Length: 2176

{"Message":"An error has occurred.","ExceptionMessage":"hey, an error!"...}

Server error 500 with a message. That's not too bad I guess, though the exception is unhandled. What if we want to log it, or send a notification email to somebody? you can put a try...catch around it sure. What if you have 5 methods? 50? all that try...catch becomes a pain in the arse. So, let's do this the easy way.

Now I add a new class to my Web API. This new class will be named GlobalExceptionLogger, but you can name yours whatever you want. Because this is only a demonstration of exception handling, I won't do anything complicated in here. I'm just setting a local variable to the Message property of the exception. Here it be:

using System.Web.Http.ExceptionHandling;

namespace BlogWebApiExceptionHandling
{
    public class GlobalExceptionLogger : ExceptionLogger
    {
        public override void Log(ExceptionLoggerContext context)
        {
            var stuff = context.Exception.Message;
        }
    }
}

There's one more line of code necessary to make this work. This new line of code goes in your WebApiConfig.cs file, within the Register method:

config.Services.Add(typeof(IExceptionLogger), new GlobalExceptionLogger());

If you now set a breakpoint back in the Log method of GlobalExceptionLogger and fire up the Web API using Fiddler, you'll see that the Log method is called for the unhandled exception. Hey, now it's globally handled! Any further Web API controllers and methods will use this thing, which is exceptionally cool. Like me! :)

Resources

What's New in ASP.Net Web API 2.1

1 comment:

  1. I just want to thank you for sharing your information and your site or blog this is simple but nice Information I’ve ever seen i like it i learn something today. Antigen Covid Test

    ReplyDelete