Tom*_*han 42 c# asp.net asp.net-web-api owin
我想在中间件组件中连接异常处理,如下所示:
public override async Task Invoke(IOwinContext context)
{
try
{
await Next.Invoke(context);
}
catch (Exception ex)
{
// Log error and return 500 response
}
}
Run Code Online (Sandbox Code Playgroud)
但是,HttpErrorResponse在我可以访问之前,我想要捕获的一些异常被Web API管道捕获并转换为s.在这个过程中,我丢失了很多关于错误的细节,所以在调试时我无法得到有用的堆栈跟踪(调试器在抛出异常时甚至不会停止 - 我必须手动单步执行代码并查看它失败的地方......).
我尝试使用以下实现添加自定义异常处理程序:
public Task HandleAsync(ExceptionHandlerContext context, CancellationToken cancellationToken)
{
var owinContext = context.Request.GetOwinContext();
owinContext.Set(Constants.ContextKeys.Exception, context.Exception);
return Task.FromResult(0);
}
Run Code Online (Sandbox Code Playgroud)
通过注册config.Services.Replace(typeof(IExceptionHandler), new MyExceptionHandler());在我的启动配置,但在执行后看着它Next.Invoke(context)通过
context.Get<Exception>(Constants.ContextKeys.Exception);
Run Code Online (Sandbox Code Playgroud)
仍然没有给我所有我想要的细节,以及没有在调试器的故障点停止.
有没有办法可以完全关闭所有内置错误处理,以便我自己的中间件可以处理它?
澄清,因为很多人似乎误解了我的追求:
Tom*_*han 18
更新:我在博客上写了这个.在研究博客文章时,我发现了一些改进的潜力; 我已经更新了这个答案的相关部分.有关为什么我认为这比其他所有建议或默认行为更好的详细信息,请阅读整篇文章:)
我现在已经采用以下方法,即使不是100%符合我的要求,它似乎也可以正常工作:
创建一个类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;
}
}
Run Code Online (Sandbox Code Playgroud)让该类替换IExceptionHandler Web API 的服务:
config.Services.Replace(typeof(IExceptionHandler), new PassthroughExceptionHandler());
Run Code Online (Sandbox Code Playgroud)创建一个中间件类,它做我想要的:
public class ExceptionHandlerMiddleware
{
public override async Task Invoke(IOwinContext context)
{
try
{
await Next?.Invoke(context);
}
catch (Exception ex)
{
// handle and/or log
}
}
}
Run Code Online (Sandbox Code Playgroud)首先在堆栈中注册该中间件:
app.Use<ExceptionHandlerMiddleware>()
.UseStageMarker(PipelineStage.Authenticate)
// other middlewares omitted for brevity
.UseStageMarker(PipelineStage.PreHandlerExecute)
.UseWebApi(config);
Run Code Online (Sandbox Code Playgroud)我还是会给那些想出来的人奖励(赏金过期......)我仍然在寻找一个更好的解决方案,例如,当一个未处理的异常被抛出时会中断.(当我在处理程序中重新抛出异常时,这种方法会使VS中断,但原始调用堆栈丢失;我必须在错误行处设置断点并再次调试,以便在抛出异常时拦截状态.)
| 归档时间: |
|
| 查看次数: |
6014 次 |
| 最近记录: |