2017-07-19 3 views
0

ich mit elmah.io für das Protokollieren von Fehlern in meiner asp.net Kernanwendung:Griff Ausnahme mit Elmah.io und ExceptionFilterAttribute

app.UseElmahIo("API_KEY", new Guid("LOG_ID")); 

Es ist nur eine Middleware und es sieht so aus:

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; 
    } 
} 

Außerdem habe ich meine benutzerdefinierte ExceptionFilter auf Fehler zu behandeln und bestimmte Nachricht an den Client zurück:

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;    
     } 
    } 

In diesem Fall, wenn ich irgendwo eine Ausnahme ausspreche, sehe ich in elmah.io einfach die Nachricht Unsuccessful status code in response. Ich glaube, es ist, weil meine ApiExceptionFilter Ausnahme zuerst behandeln und Elmah Middleware keine Ausnahme, nur schlechten Status. Wie man es löst?

PS. Startup.cs

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(); 
} 
+0

Können Sie Ihre startup.cs Datei teilen? – ThomasArdal

+0

@ThomasArdal Ich habe die Frage aktualisiert – user348173

Antwort

0

Sie sind direkt in der Tatsache, dass Ihre Ausnahmefilter schlucken die Ausnahme, bevor die elmah.io Middleware ausgeführt wird. Normalerweise würden Sie die elmah.io-Middleware als letzte in der Kette hinzufügen, um sicherzustellen, dass sich andere Middleware-Komponenten nicht so verhalten. Aber in Ihrem Fall wird der Filter ausgeführt, bevor elmah.io über den Fehler informiert wird.

Sie können dieses Problem beheben, indem:

  • Implementierung Ihrer Fehlerfilter als Middleware. Ihre aktuelle Lösung bricht wahrscheinlich einige der integrierten Middleware-Teile in ASP.NET Core.

  • Protokoll manuell Ausnahmen unhandled elmah.io, durch die UnhandledException erstreckt.Verfahren:

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

Ja, wahrscheinlich muss ich Middleware verwenden. Vielen Dank. – user348173

+0

Ich weiß nicht, welche Lösung besser ist. Es gibt einen Konflikt zwischen Filtern und Middleware. Es wäre schön, eine offizielle Dokumentation darüber zu sehen, wie man damit umgeht. Ich weiß nicht, ob es existiert. – ThomasArdal

+0

Die zweite Lösung finde ich nicht gut, denn in diesem Fall wird es zwei Einträge in elmah.io geben. Die erste ist eine manuell protokollierte Ausnahme, die zweite ist die Meldung "Erfolgloser Statuscode in Antwort", weil die Middleware von elmah den Status der Antwort überprüft. – user348173

Verwandte Themen