Service Fabric无状态Web API中的全局错误处理

时间:2017-01-05 21:59:08

标签: asp.net-web-api exception-handling owin-middleware

如何在无状态Web API中处理控制器方法的全局异常处理?我的目标是避免控制器内的try / catch语句冗长。

我能够使用我在WebAPIConfig.cs中注册的自定义ExceptionHandler通过IIS托管的Web API实现此目的。这在OWIN托管的API(如Service Fabric中)中无法正常运行。因此,在SF无状态Web API中,我创建了一个Owin中间件并在Startup.cs中注册了该中间件,但它不起作用。我的中间件代码中的响应管道中忽略了catch块。

...

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 个答案:

答案 0 :(得分:0)

经过大量的解决方案挖掘,因为有很多类似的questons,我对Web API和OWIN管道有了更好的理解。这个问题在SO中为我提供了很多信息:Disable *all* exception handling in ASP.NET Web API 2 (to make room for my own)?

首先,默认情况下处理Web API异常,这意味着处理异常,因此它不会向堆栈跟踪传播。这就是为什么,上面的catch块(来自我发布的问题)没有被调用。为了让它被调用,我需要通过这个替换Web API的IException处理程序(在startup.cs中):

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

所有这些自定义处理程序都会将异常转发到堆栈中,让OWIN全局异常中间件完成工作。

PassthroughExceptionHandler的实现如下:

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

请注意,这使用ExceptionDispatchInfo。还有其他解决方案具有不同的实现,但到目前为止,这个解决方案为我提供了我需要的内容,即将异常包装在我的OwinGlobalExceptionHandler中的常见错误响应模型中。