在 .net core Web Api 中使用自定义错误拦截器全局处理错误是否很好

问题描述

我想问你们,全局处理错误是否好,或者更好的方法是使用 try catch 块来处理它们。 您可以通过以下两种不同的方式处理错误

全局处理程序

public class ErrorDetails : Exception
{
    public int StatusCode { get; }
    public override string Message { get; }
    public override string ToString()
    {
        return JsonConvert.SerializeObject(new {Message});
    }

    public ErrorDetails(int statusCode,string message) 
    {
        Message = message;
        StatusCode = statusCode;
    }
}
public class GlobalErrorHandler
{
    private readonly RequestDelegate _next;
    public GlobalErrorHandler(RequestDelegate next)
    {
        _next = next;
    }
    public async Task InvokeAsync(HttpContext httpContext)
    {
        try
        {
            await _next(httpContext);
        }
        catch (ErrorDetails ex)
        {
            await HandleExceptionAsync(httpContext,ex);
        }
        catch (Exception ex)
        {
            await HandleExceptionAsync(httpContext,ex);
        }
    }
    private Task HandleExceptionAsync(HttpContext context,ErrorDetails exception)
    {
        context.Response.ContentType = "application/json";
        context.Response.StatusCode = exception.StatusCode;
        return context.Response.WriteAsync(exception.ToString());
    }
    private Task HandleExceptionAsync(HttpContext context,Exception exception)
    {
        context.Response.ContentType = "application/json";
        context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
        return context.Response.WriteAsync(exception.ToString());
    }
}

然后只是在代码中抛出错误或者还有第二种方法

public async Task<Response<User>> Create(User user)
    {
        try
        {
            var userFromDatabase = await _repository.Queryable().FirstOrDefaultAsync(x => x.Email == user.Email);
            if (userFromDatabase != null) return new Response<User>("Taki użytkownik już istnieje.");
            user.Password = new PasswordHasher<string?>().HashPassword(null,user.Password);
            await _repository.InsertAsync(user);
            return new Response<User>(user);
        }
        catch(Exception ex)
        {
            return new Response<User>($"Error: {ex.Message}");
        }
        
    }
public class Response<TEntity> where TEntity : class
{
    public readonly string Message;
    public readonly bool Success;
    public readonly TEntity Entity;
    public readonly List<TEntity> Entities;
    private Response(TEntity entity,List<TEntity> entities,string message,bool success)
    {
        Entity = entity;
        Entities = entities;
        Success = success;
        Message = message;
    }
    public Response(string message) : this(null,null,message,false) {}
    public Response(TEntity entity) : this(entity,true) {}
    public Response(List<TEntity> entities) : this(null,entities,true) {}
}

这种方法基于发送到控制器的响应对象,然后在控制器中基于我们发送给用户对象或消息的 Response<TEntity>.Success 值。

我的问题是:全局错误处理是否可以,或者最好在每个服务中使用 try catch。

提前致谢:)

解决方法

在我看来,全局错误处理程序更有帮助。特别是当您有自己的自定义异常需要以特定方式处理时。它还会处理任何未处理的异常并优雅地处理它。