![](/img/trans.png)
[英]Application_Error in global.asax not catching errors in WebAPI
[英]Neither the Global Exception Filter or the Application_Error are Catching Unhandled Exceptions
我有一個名為LogErrorAttribute
的全局異常過濾器:
public class LogErrorAttribute : IExceptionFilter
{
private ILogUtils logUtils;
public void OnException(ExceptionContext filterContext)
{
if (this.logUtils == null)
{
this.logUtils = StructureMapConfig.Container.GetInstance<ILogUtils>();
}
this.logUtils.LogError(HttpContext.Current.User.Identity.GetUserId(), "Unknown error.", filterContext.Exception);
}
}
它與標准HandleErrorAttribute
過濾器一起注冊:
filters.Add(new LogErrorAttribute());
filters.Add(new HandleErrorAttribute());
我正在注冊這樣的過濾器:
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
我還有一個Application_Error
后備:
protected void Application_Error()
{
var exception = Server.GetLastError();
Server.ClearError();
var httpException = exception as HttpException;
//Logging goes here
var routeData = new RouteData();
routeData.Values["controller"] = "Error";
routeData.Values["action"] = "Index";
if (httpException != null)
{
if (httpException.GetHttpCode() == 404)
{
routeData.Values["action"] = "NotFound";
}
Response.StatusCode = httpException.GetHttpCode();
}
else
{
Response.StatusCode = 500;
}
// Avoid IIS7 getting involved
Response.TrySkipIisCustomErrors = true;
// Execute the error controller
if (exception != null)
{
this.errorLogger.Log(LogLevel.Error, "An unknown exception has occurred.", exception);
}
else if (httpException != null)
{
this.errorLogger.Log(LogLevel.Error, "An unknown HTTP exception has occurred.", httpException);
}
else
{
this.errorLogger.Log(LogLevel.Error, "An unknown error has occurred.");
}
}
現在,我有一個API控制器,它從數據庫中獲取一些數據,然后使用AutoMapper
將模型映射到視圖模型:
var viewModels = AutoMapper.Mapper.Map(users, new List<UserViewModel>());
在AutoMapper
配置中,自定義解析器為其中一個屬性執行:
var appModuleAssignments = this.appModuleAssignmentManager.Get(userId);
var appModules = appModuleAssignments.Select(x => this.appModuleManager.Get(x.AppModuleId));
return AutoMapper.Mapper.Map(appModules, new List<AppModuleViewModel>());
目前我正在強制appModuleManager.Get
語句拋出一個常規異常:
throw new Exception("Testing global filter.");
這隨后會在AutoMapper
引發異常,這兩個異常都是未處理的,但是全局過濾器或Application_Error
都沒有收到此異常。
我在這做錯了什么?
自發布以來我做過的幾件事情:
customErrors
屬性添加到Web.config
以將其on
。 HandleErrorAttribute
全局過濾器,因為我意識到它正在設置錯誤,如果它甚至在運行的話。 我不希望它仍然在執行,因為這個錯誤發生在控制器外部,但它可能會在稍后發生。 簡短的回答是您要添加MVC異常過濾器而不是Web API異常過濾器。
您的實現檢查ExceptionContext
而不是HttpActionExecutedContext
public override void OnException(HttpActionExecutedContext actionExecutedContext)
由於框架將引發Http異常而不是MVC異常 ,因此不會觸發OnException
覆蓋方法。
所以,一個更完整的例子:
public class CustomExceptionFilter : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext actionExecutedContext)
{
message = "Web API Error";
status = HttpStatusCode.InternalServerError;
actionExecutedContext.Response = new HttpResponseMessage()
{
Content = new StringContent(message, System.Text.Encoding.UTF8, "text/plain"),
StatusCode = status
};
base.OnException(actionExecutedContext);
}
}
另一個重要步驟是在Register(HttpConfiguration config)
方法中在WebApiConfig.cs中Register(HttpConfiguration config)
Global Web API異常過濾器。
public static void Register(HttpConfiguration config)
{
...
config.Filters.Add(new CustomExceptionFilter());
}
Dave Alperovich的回答將通過使用HttpActionExecutedContext來解決您的問題
public override void OnException(HttpActionExecutedContext context)
但是,當您嘗試捕獲應用程序可能生成的所有可能異常時,除了異常過濾器之外,還應使用消息處理程序。 詳細解釋可以在這里找到 - http://www.asp.net/web-api/overview/error-handling/web-api-global-error-handling 。
總之,在許多情況下,異常過濾器無法處理。 例如:
因此, 如果應用程序中的任何位置發生未處理的錯誤,您的異常處理程序將捕獲它並允許您采取特定操作 。
//Global exception handler that will be used to catch any error
public class MyExceptionHandler : ExceptionHandler
{
private class ErrorInformation
{
public string Message { get; set; }
public DateTime ErrorDate { get; set; }
}
public override void Handle(ExceptionHandlerContext context)
{
context.Result = new ResponseMessageResult(context.Request.CreateResponse(HttpStatusCode.InternalServerError,
new ErrorInformation { Message="An unexpected error occured. Please try again later.", ErrorDate=DateTime.UtcNow }));
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.