首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用Elmah.io和ExceptionFilterAttribute处理异常

用Elmah.io和ExceptionFilterAttribute处理异常
EN

Stack Overflow用户
提问于 2017-07-19 17:23:48
回答 1查看 662关注 0票数 1

我使用elmah.io记录asp.net核心应用程序中的错误:

代码语言:javascript
复制
app.UseElmahIo("API_KEY", new Guid("LOG_ID"));

它只是一个中间件,它看起来像:

代码语言:javascript
复制
 public async Task Invoke(HttpContext context)
 {
    try
    {
       await _next.Invoke(context);
       await MessageShipper.ShipAsync(_apiKey, _logId, "Unsuccessful status code in response", context, _settings);                    
     }
     catch (Exception exception)
     {
        await exception.ShipAsync(_apiKey, _logId, context, _settings);
        throw;
     }
}

此外,我还有我的自定义ExceptionFilter来处理错误并向客户端返回特定的消息:

代码语言:javascript
复制
public class ApiExceptionFilter : ExceptionFilterAttribute
    {           
        private ApiError _apiError;

        public override void OnException(ExceptionContext context)
        {
            if (context.Exception is ApiException)
            {
                HandleKnownError(context);
            }
            else if (context.Exception is UnauthorizedAccessException)
            {
                HandleUnauthorizedException(context);
            }
            else
            {
                UnhandeledException(context);
            }

            context.Result = new JsonResult(_apiError);

            base.OnException(context);
        }

        private void UnhandeledException(ExceptionContext context)
        {
            var msg = context.Exception.GetBaseException().Message;
            string stack = context.Exception.StackTrace;
            _apiError = new ApiError(msg) {Detail = stack};

            context.HttpContext.Response.StatusCode = 500;          
        }       

        private void HandleKnownError(ExceptionContext context)
        {
            var ex = context.Exception as ApiException;
            context.Exception = null;
            _apiError = new ApiError(ex.Message);

            context.HttpContext.Response.StatusCode = ex.StatusCode;            
        }
    }

在这种情况下,如果我在某个地方抛出异常,在elmah.io中我只会看到消息Unsuccessful status code in response。我相信这是因为我的ApiExceptionFilter首先处理异常,而elmah中间件没有异常,只是状态不好。如何解决这个问题?

PS。Startup.cs

代码语言:javascript
复制
public void ConfigureServices(IServiceCollection services)
{
   services.Configure<Settings>(Configuration);
   ConfigureCors(services);

   services.AddMvc(o =>
   {
      o.Filters.Add(new ApiResponseWrapper());
      o.Filters.Add(typeof(ApiExceptionFilter));
   })
   ... a lot of my services
}

public void Configure(IApplicationBuilder app, 
            IHostingEnvironment env, 
            ILoggerFactory loggerFactory,
            IServiceProvider serviceProvider)
{
   loggerFactory.AddConsole(Configuration.GetSection("Logging"));
   loggerFactory.AddDebug();
   var logPath = Path.Combine(env.WebRootPath, "Logs/App-log-{Date}.txt");
   loggerFactory.AddFile(logPath);

   app.UseElmahTo("API",new Guid("LOG_ID"));
   app.UseCors("CorsPolicy");
   ConfigureAuth(app, env);
   app.UseMvc();
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-07-20 06:37:58

您正确地认识到,您的异常过滤器在执行elmah.io中间件之前吞噬了异常。您通常会添加elmah.io中间件作为链中的最后一个,以确保其他中间件的行为不像这样。但在您的示例中,在elmah.io收到错误通知之前将执行筛选器。

你可以通过以下方式解决这个问题:

  • 将错误筛选器实现为中间件。您当前的解决方案可能会破坏ASP.NET核心中的一些内置中间件。
  • 通过扩展elmah.io方法,手动记录未处理的异常到UnhandledException
代码语言:javascript
复制
private void UnhandeledException(ExceptionContext context)
{
    context.Exception.Ship("API_KEY", new System.Guid("LOG_ID"), context.HttpContext);

    var msg = context.Exception.GetBaseException().Message;
    string stack = context.Exception.StackTrace;
    _apiError = new ApiError(msg) { Detail = stack };

    context.HttpContext.Response.StatusCode = 500;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45197201

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档