ExceptionFilter for exception handling in AspNet Core Web API

Writing try/catch in every method for exception handling is quite time-consuming and requires extra efforts too. To avoid this approach, we can set up a global exception handler in our project using techniques like error handling middleware, exception filter etc. In this post, I will show you how you can use the ExceptionFilter as an exception handler in your project.

For this, you need to create your own custom exception filter class use interface IExceptionFilter or IExceptionFilterAsync.

public class MyExceptionFilter : IExceptionFilter
    {
        public void OnException(ExceptionContext context)
        {
            throw new NotImplementedException();
        }
    }

Now we need to define OnException method as per our requirement. Here you can handle the exception as your requirements like handling server generated exception one way and custom exception another way. You can do other stuff like injecting logger to log the errors etc. Here is a simple example.

//You can inject any other class, services in ctor and use in `OnException` method defination
        //public MyExceptionFilter(IConfiguration configuration, IMyService myService)
        //{

        //}

        public void OnException(ExceptionContext context)
        {
            HttpStatusCode status = HttpStatusCode.InternalServerError;
            var message = "Server error occurred.";

            var exceptionType = context.Exception.GetType();
            if (exceptionType is MyCustomException) //Checking for my custom exception type
            {
                message = context.Exception.Message;
            }

            //You can enable logging error

            context.ExceptionHandled = true;
            HttpResponse response = context.HttpContext.Response;
            response.StatusCode = (int)status;
            response.ContentType = "application/json";
            context.Result = new ObjectResult(new ApiResponse { Message = message, Data = null });
        }

In this example, If an exception is custom i.e. MyCustomException type then I am pulling exception message from exception object else I am just sending Server error occurred as a general message and at last I am returning ApiResponse object wrapping by ObjectResult. ApiResponse is just a class contains two property Message and Data. Once you handled the exception, don’t forget to set the ExceptionHandled property of ExceptionContext to true as shown above.

Now once you finished building custom exception filter class you need to register that in ConfugureServices method so that it can be used as a global exception filter. Here is how to do it.

services.AddMvc(config =>
                {
                    config.Filters.Add(typeof(MyExceptionFilter));
                })
                .SetCompatibilityVersion(CompatibilityVersion.Version_2_1));

Now you can try throwing an error from controller’s action and you can see the result as a JSON object.

Based on MS docs, exception filter alone is enough for global exception handling. You can read about the pros and cons of Exception filter here.

Happy Coding!