Identity
Identity

Reputation: 1673

MVC error handling in Owin Middleware

When certain exceptions are thrown in controllers, I want to catch those exceptions and do some extra logic.

I was able to achieve this with a custom IExceptionFilter that is added to the global filters list.

However, I preffer to handle these exception within a custom Owin middleware. My middleware looks like this:

      try
        {

            await Next.Invoke(context);
        }
        catch (AdalSilentTokenAcquisitionException e)
        {
           //custom logic
        }

This piece of code does not work, it looks like the exception is already catched and handled in MVC. Is there a way to skip the exception processing from MVC and let the middleware catch the exception?

Upvotes: 4

Views: 3066

Answers (2)

Identity
Identity

Reputation: 1673

Update: I've found a cleaner approach, see my updated code below. With this approach, you don't need a custom Exception Filter and best of all, you don't need the HttpContext ambient service locator pattern in your Owin middleware.

I have a working approach in MVC, however, somehow it doesn't feel very comfortable, so I would appreciate other people's opinion.

First of all, make sure there are no exception handlers added in the GlobalFilters of MVC.

Add this method to the global asax:

    protected void Application_Error(object sender, EventArgs e)
    {
        var lastException = Server.GetLastError();
        if (lastException != null)
        {
            HttpContext.Current.GetOwinContext().Set("lastException", lastException);
        }
    }

The middleware that rethrows the exception

public class RethrowExceptionsMiddleware : OwinMiddleware
{
    public RethrowExceptionsMiddleware(OwinMiddleware next) : base(next)
    {
    }

    public override async Task Invoke(IOwinContext context)
    {
        await Next.Invoke(context);
        var exception = context.Get<Exception>("lastException");
        if (exception != null)
        {
            var info = ExceptionDispatchInfo.Capture(exception);
            info.Throw();
        }
    }
}

Upvotes: 5

Tomas Aschan
Tomas Aschan

Reputation: 60574

There's no perfect way to do this (that I know of), but you can replace the default IExceptionHandler with one that just passes the error through to the rest of the stack.

I did some extensive digging about this, and there really doesn't seem to be a better way for now.

Upvotes: 2

Related Questions