Global Error Handling in Service Fabric Stateless Web API

1k views Asked by At

How should I handle global exception handling for my controller methods in stateless web API? My goal is to avoid verbosity of try/catch statements inside my controller.

I was able to achieve this with IIS hosted Web API using a custom ExceptionHandler which I register in my WebAPIConfig.cs. This won't work right-off-the-bat in OWIN hosted API (like in Service Fabric). So in SF stateless web API, I created an Owin middleware and registered that middleware in Startup.cs but it does not work. The catch block is ignored in the response pipeline in my middleware code.

...

public override async Task Invoke(IOwinContext context)
{
    try
    {
        //It goes here
        await Next.Invoke(context);
    }
    catch (Exception ex)
    {
        //This catch block does not get called????
        HandleException(ex, context);
    }
}
1

There are 1 answers

0
alltej On

After a lot of digging for solutions, since there has been quite a lot of similar questons out there, I gained a better understanding about the Web API and OWIN pipeline. This question here in SO provided me a lot of info:Disable *all* exception handling in ASP.NET Web API 2 (to make room for my own)?

First-off, Web API exceptions are handled by default and that means the exception is handled so it does not propagate up the stacktrace. And that's the reason why, the catch block above (from my posted question) does not get called. In order for it to get called, I need to replace the IException handler of the Web API(in startup.cs) via this:

config.Services.Replace(typeof(IExceptionHandler), new PassthroughExceptionHandler());

All this custom handler does is forward the exception down the stack and let the OWIN global exception middleware do the work.

The PassthroughExceptionHandler is implemented like this:

public class PassthroughExceptionHandler : IExceptionHandler
{
    public Task HandleAsync(ExceptionHandlerContext context, CancellationToken cancellationToken)
    {
        var info = ExceptionDispatchInfo.Capture(context.Exception);
        info.Throw();
    }
}

Note that this uses ExceptionDispatchInfo . There are other solutions that have a different implementation but so far this one provided me what I need which is to ulimately wrap the exception into my common error response model in my OwinGlobalExceptionHandler.