繁体   English   中英

同步动作场景中的 ExceptionFilter 堆栈跟踪

[英]ExceptionFilter stack trace in synchronous action scenario

我在控制器中有一个简单的同步操作,它会引发如下异常:

[RoutePrefix("")]
public class MyController : ApiController
{
    [Route("")]
    public HttpResponseMessage Get()
    {
        throw new Exception("whatever");
        return Request.CreateResponse(HttpStatusCode.OK, "response");
    }
}

我还有一个 ExceptionFilterAttribute 来获取应用程序中发生的异常

public class MyExceptionFilterAttribute : ExceptionFilterAttribute
{
    public override void OnException(HttpActionExecutedContext actionContext)
    {
        var ex = actionContext.Exception;
        // Log ex, etc.
    }
}

一切正常,因为我确实掌握了MyExceptionFilterAttribute中的异常。 问题是堆栈跟踪。 这是它的样子:

at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Web.Http.ApiController.<InvokeActionWithExceptionFilters>d__1.MoveNext()"

所以我的问题是:如何获得“真正的”堆栈跟踪(指向控制器中发生异常的方法)?

更一般地说,因为显然有一些我不明白的东西,在这种情况下异步来自哪里? 当 web api 遇到控制器方法时,它是否会自动创建一个异步任务?

我正在使用 Web API v2.0(包 v5.0.0 )并且无法升级到更新的版本(复杂的故事)。

更多信息:我遇到了这个问题,所以我尝试从 ActionFilterAttribute 而不是 ExceptionFilterAttribute 继承,但是当ActionFilterAttribute被击中时,堆栈跟踪已经看起来像上面的那样。

如果您被迫不升级 Web API 包,那么您最好的选择可能是完全避免使用ActionFilters来处理异常。

更好(和全局)的方法是创建一个ExceptionHandler来替换 Web API 配置中的默认实现:

public class MyExceptionHandler : ExceptionHandler
{
    public override void Handle(ExceptionHandlerContext context)
    {
        var ex = context.Exception;

        //log exception, do stuff

        context.Result = new InternalServerErrorResult(context.Request);
    }

    public override bool ShouldHandle(ExceptionHandlerContext context)
    {
        bool shouldHandle;

        //logic to check if you should handle the exception or not

        return shouldHandle;
    }
}

WebApiConfig.cs (假设config是您的HttpConfiguration对象):

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

相反,如果您只想记录异常(而不是以某种方式处理它),那么您可以以类似的方式实现ExceptionLogger

public class MyExceptionLogger : ExceptionLogger
{
    public override void Log(ExceptionLoggerContext context)
    {
        MyLogger.Log(LogLevel.Error, context.Exception, "some message");
    }
}

然后再次:

config.Services.Replace(typeof(IExceptionLogger), new MyExceptionLogger());

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM