簡體   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