禁用ASP.NET Web API 2中的* all *异常处理(为我自己腾出空间)? [英] Disable *all* exception handling in ASP.NET Web API 2 (to make room for my own)?
问题描述
我想在中间件组件中连接异常处理,如下所示:
public override async Task Invoke(IOwinContext context)
{
try
{
await Next.Invoke(context);
}
catch (Exception ex)
{
// Log error and return 500 response
}
}
但是,我想捕获的一些异常在被Web API管道捕获并转换为HttpErrorResponse
之前就可以获取.在此过程中,我丢失了许多有关错误的详细信息,因此在进行调试等操作时,我无法获得有用的堆栈跟踪信息(引发异常时调试器甚至都不会停止-我必须手动浏览代码,看看失败了...).
我尝试通过以下实现添加自定义异常处理程序:
public Task HandleAsync(ExceptionHandlerContext context, CancellationToken cancellationToken)
{
var owinContext = context.Request.GetOwinContext();
owinContext.Set(Constants.ContextKeys.Exception, context.Exception);
return Task.FromResult(0);
}
在我的启动配置中通过config.Services.Replace(typeof(IExceptionHandler), new MyExceptionHandler());
注册,但是在通过
context.Get<Exception>(Constants.ContextKeys.Exception);
执行后通过
context.Get<Exception>(Constants.ContextKeys.Exception);
查看
context.Get<Exception>(Constants.ContextKeys.Exception);
still 并没有提供我想要的所有详细信息,也没有提供调试器在故障点停止的信息.
有没有办法完全 关闭所有内置错误处理,以便我自己的中间件可以解决?
澄清,因为很多人似乎误会了我的追求:
- Web API中的内置错误处理功能捕获一些(但不是全部)异常并将其重写为500个响应.
- 我想捕获所有 异常,进行一些日志记录,然后然后用我选择的信息发出500个响应 (对于大多数情况,请参阅下一个项目符号.)
- 还有一些表示业务逻辑故障的异常,我想为其返回40倍的错误.
- 我希望它位于(app)管道的顶部,即在请求生命周期中包装其他其他
- 我想使用OWIN来处理此问题,以使其可移植到将来可能出现的自托管方案(即,并非始终将这个应用程序始终托管在IIS上是一成不变的-HTTP模块,Global.asax.cs等)在这里不相关).
更新: 解决方案
Update: I blogged about this. When researching the blog post, I found some potential for improvement; I've updated the relevant parts of this answer. For more detail on why I think this is better than all other suggestions here, or the default behavior, read the entire post :)
I have now gone with the following approach, which seems to work OK, even if not 100 % compliant with what I was looking for:
Create a class
PassthroughExceptionHandler
:public class PassthroughExceptionHandler : IExceptionHandler { public Task HandleAsync(ExceptionHandlerContext context, CancellationToken cancellationToken) { // don't just throw the exception; that will ruin the stack trace var info = ExceptionDispatchInfo.Capture(context.Exception); info.Throw(); return Task.CompletedTask; } }
Let that class replace the
IExceptionHandler
service of Web API:config.Services.Replace(typeof(IExceptionHandler), new PassthroughExceptionHandler());
Create a middleware class which does what I want:
public class ExceptionHandlerMiddleware { public override async Task Invoke(IOwinContext context) { try { await Next?.Invoke(context); } catch (Exception ex) { // handle and/or log } } }
Register that middleware first in the stack:
app.Use<ExceptionHandlerMiddleware>() .UseStageMarker(PipelineStage.Authenticate) // other middlewares omitted for brevity .UseStageMarker(PipelineStage.PreHandlerExecute) .UseWebApi(config);
I will still award the bounty to anyone who comes up with (bounty expired...) I'm still looking for a better solution, which, for example, breaks when an unhandled exception is thrown. (This approach makes VS break when I rethrow the exception in the handler, but the original call stack is lost; I have to set a breakpoint at the faulting line and debug again to be able to intercept the state when an exception is thrown.)
这篇关于禁用ASP.NET Web API 2中的* all *异常处理(为我自己腾出空间)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!