场景: 我有一个带有异常处理中间件的.net核心2.2 Web API。只要应用程序中发生异常(在MVC层内部),异常中间件就会捕获该异常,并将其作为内部服务器错误返回给前端并记录到kibana。
问题:当出现问题时,这一切都很好,但有时我想通知发生问题的调用应用程序。即“在数据库中找不到记录!”或“无法将其转换为该字符!”
我的解决方案:我使用应用程序异常(不是很好-我知道)来带走错误中间件,以将其返回到前端。这样做一直很好,但是由于必须抛出大量异常,因此在代码周围产生了很多噪音。我对此方法不满意,并坚信必须有更好的解决方案。
我的应用程序体系结构:我遵循传统的n层应用程序布局,即服务(业务逻辑)和存储库(DAL)都在互相交谈。我最好希望在所有这些层中优雅地将所有问题反馈给用户。
我已经考虑了一段时间,但不确定最好的解决方法是什么。任何建议将不胜感激。
答案 0 :(得分:1)
我使用一种操作结果模式(非官方模式)。
原理是返回包含以下内容的新Type:
请考虑以下课程:
public class OperationResult
{
protected OperationResult()
{
this.Success = true;
}
protected OperationResult(string message)
{
this.Success = false;
this.FailureMessage = message;
}
protected OperationResult(Exception ex)
{
this.Success = false;
this.Exception = ex;
}
public bool Success { get; protected set; }
public string FailureMessage { get; protected set; }
public Exception Exception { get; protected set; }
public static OperationResult SuccessResult()
{
return new OperationResult();
}
public static OperationResult FailureResult(string message)
{
return new OperationResult(message);
}
public static OperationResult ExceptionResult(Exception ex)
{
return new OperationResult(ex);
}
public bool IsException()
{
return this.Exception != null;
}
}
然后,您可以轻松地修改OperationResult或创建一个从OperationResult继承但使用通用类型参数的类。
一些例子:
答案 1 :(得分:0)
根据Microsoft的标准,在出现4xx / 5xx异常的情况下,最好使用ProblemDetails对象-
以下是自定义的RequestDelegate方法,您可以在ApiExceptionHandler中使用该方法来处理异常。希望这会有所帮助!
public async Task RequestDelegate(HttpContext context) { var exception = context.Features.Get<IExceptionHandlerFeature>().Error; var problemDetails = new ProblemDetails { Title = "An unexpected error occurred!", Status = GetStatusCode(exception), Detail = _env.IsDevelopment() ? exception.Message : "An unexpected error occurred!", Instance = $"{Environment.MachineName}:{context.TraceIdentifier}:{Guid.NewGuid()}" }; _logger.LogError($"Exception thrown. StatusCode: {problemDetails.Status}. Instance: {problemDetails.Instance}", exception); context.Response.StatusCode = problemDetails.Status.Value; context.Response.WriteJson(problemDetails, "application/problem+json"); await Task.CompletedTask; }