登录中间件异常处理程序

时间:2019-05-02 14:01:45

标签: c# exception .net-core

在分层的Web应用程序中,我想将所有错误日志记录从“域”和“数据”层移到全局异常处理程序,但是我不确定要权衡些什么。我想删除任何日志记录调用,并用更具体的Exception(如有必要,可以自定义)替换它,或者删除捕获:

try{
   . . . 
}
catch
{
   Logger.Error('Info'); // <-- remove this for a: throw new CustomException('Info', ex);
   throw;                // <-- then, remove this line
}

在WebAPI中有一个作为中间件配置的全局异常处理程序,然后作为处理程序方法的一部分,我将记录发生的任何异常情况

// Startup.cs
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseExceptionHandler(
    error =>
    {
        GlobalExceptionHandler.ErrorHandling(error, env);
    });
}

// GlobalExceptionHandler.cs
public static class GlobalExceptionHandler
{
    public static void ErrorHandling(IApplicationBuilder errorApp, IHostingEnvironment env)
    {
        errorApp.Run(async context =>
        {
            .
            .
            .

            Log.Current.Error(exception.Message, () => exception);
        }
    }
}

是否可能是避免重复记录记录的更好方法?

1 个答案:

答案 0 :(得分:0)

在我构建的应用程序中,我喜欢使用您建议的方法。我将发布我使用的中间件:

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using MyProject.Interfaces;

namespace MyProject.Middlewares
{
    public class ErrorReporterMiddleware
    {
        private readonly RequestDelegate RequestDelegate;

        public ErrorReporterMiddleware(RequestDelegate requestDelegate)
        {
            RequestDelegate = requestDelegate ?? throw new ArgumentNullException(nameof(requestDelegate));
        }

        public async Task Invoke(HttpContext httpContext, IErrorReporter errorReporter)
        {
            try
            {
                await RequestDelegate(httpContext);
            }
            catch (Exception e)
            {
                await errorReporter?.CaptureAsync(e);
                throw;
            }
        }
    }
}

在这种情况下,IErrorReporter是我在MyProject.Interfaces命名空间中定义的接口。我用它来抽象日志记录服务:

using System;
using System.Threading.Tasks;

namespace MyProject.Interfaces
{
    public interface IErrorReporter
    {
        Task CaptureAsync(Exception exception);
        Task CaptureAsync(string message);
    }
}

然后在Startup.cs中,我将以下行添加到Configure方法中:

app.UseMiddleware<ErrorReporterMiddleware>();

没什么特别的,但我认为这是一种干净的方法。