我在Controller中有一个简单的同步动作,它会抛出一个异常,如下所示:
[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(packages v5.0.0),无法升级到更新的版本(复杂的故事)。
更多信息:我遇到了this question所以我尝试从ActionFilterAttribute继承而不是ExceptionFilterAttribute,但是当ActionFilterAttribute
被点击时,堆栈跟踪看起来就像上面那样。
答案 0 :(得分:1)
如果您被迫不升级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());