问题描述
我想问你们,全局处理错误是否好,或者更好的方法是使用 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。
提前致谢:)
解决方法
在我看来,全局错误处理程序更有帮助。特别是当您有自己的自定义异常需要以特定方式处理时。它还会处理任何未处理的异常并优雅地处理它。