Exception handling is one of the most important part of any application that needs to be addressed and implemented properly. With ASP.NET Core, things have changed and are in better shape to implement exception handling. Implementing exception handling for every action method in API, is quite time-consuming and requires extra efforts. So, in this post, find out how to implement global exception handling in ASP.NET Core Web API.

The benefit of implementing global exception handling is that you need to implement in at one place. Any exception occurs in your application will be handled, even when you add new controllers or new methods.

Global Exception Handling in ASP.NET Core Web APIs

Exceptions are something inevitable in any application This can mostly occur due to external factors as well, like network issues and so on. If these exceptions are not handled within the application, it may even lead the entire application to terminations and data loss.

Here are a couple of ways to implement an exception handling globally.

First Method

Using IExceptionHandler and creating custom exception handler. The interface looks like,

namespace GlobalException

{

public interface IExceptionHandler:IFilterMetadata

{

void OnException(ExceptionContext context);

}

}

As you can see, there is only one method which needs to be implemented. This method gets called in case of any unhandled exception. So, let’s create a class which implements IExceptionHandler.

public class CustomExceptionHandler : IExceptionFilter

{

public void OnException(ExceptionContext context)

{

HttpStatusCode status = HttpStatusCode.InternalServerError;

String message = String.Empty;

var exceptionType = context.Exception.GetType();

if (exceptionType == typeof(UnauthorizedAccessException))

{

message = “Unauthorized Access”;

status = HttpStatusCode.Unauthorized;

}

else if (exceptionType == typeof(NotImplementedException))

{

message = “A server error occurred.”;

status = HttpStatusCode.NotImplemented;

}

else

{

message = context.Exception.Message;

status = HttpStatusCode.NotFound;

}

context.ExceptionHandled = true;

HttpResponse response = context.HttpContext.Response;

response.StatusCode = (int)status;

response.ContentType = “application/json”;

var err = message + ” ” + context.Exception.StackTrace;

response.WriteAsync(err);

}

}

Here, the code checks for the exception type and set the message and status properties accordingly.

Finally, add the filter in the ConfigureServices method of Startup class.

public void ConfigureServices(IServiceCollection services)

{

services.AddControllers();

services.AddSwaggerGen(c =>

{

c.SwaggerDoc(“v1”, new OpenApiInfo { Title = “GlobalException”, Version = “v1” });

});

services.AddMvc(

config => {

config.Filters.Add(typeof(CustomExceptionHandler));

});

}

Now when you run the application and exception occurs, then it will be handled on Exception method. In one of the controller actions divide a number by zero (0).  A custom exception class can also be created to infuse custom error details.

[HttpGet]

public decimal Get()

{

var rng = 9;

return rng/0 ;

}

The following exception will be displayed.

Global Exception Handling in ASP.Net Core

Second Method

ASP.NET Core is shipped with some inbuilt middleware components. And one of the inbuilt ASP.NET Core diagnostic middleware is   UseExceptionHandler.

The middleware UseExceptionHandler can be used to handle exceptions globally. You can get all the details of the exception object (Stack Trace, Inner exception, message etc..) and display them on-screen. You can implement like this.

app.UseExceptionHandler(

options =>

{

options.Run(

async context =>

{

context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;

context.Response.ContentType = “text/html”;

var ex = context.Features.Get<IExceptionHandlerFeature>();

if (ex != null)

{

var err = $”<h1>Error: {ex.Error.Message}</h1>{ex.Error.StackTrace }”;

await context.Response.WriteAsync(err).ConfigureAwait(false);

}

});

}

);

Put this inside configure() of startup.cs file. Let’s throw some exception to test it. In one of the controller action divide a number by zero (0).

[HttpGet]

public decimal Get()

{

var rng = 9;

return rng/0 ;

}

Run the application and you should see following. You can also debug and check in case of exception, it is hitting the app.UseExceptionHandler() code.

Global Exception Handling in ASP.Net Core

Get started with Exception Handling

This post highlights two approaches to handling exceptions globally, either via inbuilt middleware or an exception filter.  This approach will speed up the development process and help developers to focus on implementing the business logic.  This approach also helps test the exception handling separately and ensures that every error in your Web API application is caught.

Sohan
Sohan
Technical Lead