asp.net-mvcasp.net-web-apiasp.net-web-api2

ExceptionFilter difference between OnExceptionAsync vs.OnException


That's it.

When writing custom exception filter in MVC or Web APO, what is the difference between OnExceptionAsync and OnException methods? Is it so that OnExceptionAsync is called only when using asynchronous controllers? Or both are called?

When to use which?

How to use OnExceptionAsync which returns task result?

Some base code to illustrate:

public class ApiExceptionFilterAttribute : ExceptionFilterAttribute
{
    public override void OnException(HttpActionExecutedContext actionExecutedContext)
    {
        //TODO exception handling
    }

    public override Task OnExceptionAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken)
    {
        //TODO exception handling
    }
}

Solution

  • I think OnExceptionAsync is used with async Actions.

    If you want a simple scenario like sending a serializable description of the error, you can override OnException and not OnExceptionAsync, since OnExceptionAsync invokes OnException in the ExceptionFilterAttribute default implementation:

    public override void OnException(System.Web.Http.Filters.HttpActionExecutedContext actionExecutedContext)
    {
        actionExecutedContext.Response = actionExecutedContext.Request.CreateResponse(HttpStatusCode.InternalServerError, new 
        {
            Message = "An unexpected error has occured",
            Description = actionExecutedContext.Exception.Message
        });
    
        actionExecutedContext.Response.Headers.CacheControl = new System.Net.Http.Headers.CacheControlHeaderValue()
        {
            NoCache = true,
            NoStore = true
        };
    }
    

    But you may want to log the exception in a database and take advantage of the async behavior :

    public override async Task OnExceptionAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken)
    {
        await LogException(actionExecutedContext.Exception);
    }
    

    The async and await keywords will do the job for you to manage the async behavior. You don't need to return the Task object.