Handling Exceptions in WebApi globally

Handling exceptions can be such a hassle. Thankfully the WebAPI pipeline can help alot.
Utilizing the ExceptionFilterAttribute class can create
a consistent and simple way of returning great error responses for your API – like this

Lets get started.

First of all we need:

The Error Model:

The error interface:

We have 4 things here
1. ExceptionType – The type of error
2. A HttpStatusCode – Because returning the statuscode can prove useful to consumers
3. A Code – I use this for the httpstatuscode message
4. A List of Errors
1. Exception Type

Just an enum. I tend to use only Error, but it allows for a more gradient approach if needed.
2. HttpStatusCode
Thankfully the System.Net namespace provides most HttpStatusCodes as enum, so I just utilize this.
3. Code
I use this for the string interpretation of the httpStatusCode, but could be an internal code as well.
4. List of Errors

The above class consists of a Reason phrase and a message to go with this phrase
The “reasons” is also encapsulated as enums, but will be converted into their string representations in the inherited ApiException Class

The derived ApiException Class

Not alot to it. A few constructors, but it should explain itself pretty well.
“All of this is all good and fine, but how do we handle exceptions globally?” you ask.

The GlobalExceptionAttribute

it basically just checks which type of exception was thrown, and acts accordingly, notably typeof(ApiException). Any “unhandled” errors is thrown as “internal server error”. This is also where you would put any logging, as all exceptions will go through this filter. (I have left this out).
The above attribute should be applied in the WebApiConfig.cs file.

As you can see from the following part of the attribute

We check for any errors with typeof(ApiException), but we haven’t implemented the error type yet.
So in any Actions where you would normally return errors, you throw a new ApiException instead.

The above would cause our API to return a response, with a responsecode of 404 and the following body