问题描述
我有一个从外部API调用端点的服务。我开发了一个自定义的中间件,用于处理这些API调用中可能出现的异常并将它们记录下来。但是,尽管中间件在 Invoke方法中包含try and catch块,但是在catch块捕获了Exception之后,我的应用程序的流程被中断了。尽管应用程序继续运行,但是流程只是结束了。当此应用程序正在执行同步数据的作业时,我需要流程继续进行(并记录可能的异常,如上所述)。
任何人都已经经历过或有任何线索如何使流程继续进行?有更好的方法吗?我完全愿意征求意见。
这是我的代码:
public class ApiException
{
private readonly RequestDelegate _next;
private readonly ILogger<ApiException> _logger;
private readonly ApiExceptionOptions _options;
public ApiException(ApiExceptionOptions options,RequestDelegate next,ILogger<ApiException> logger)
{
_next = next;
_logger = logger;
_options = options;
}
public async Task Invoke(HttpContext context /* other dependencies */)
{
try
{
await _next(context);
}
catch (Exception ex)
{
await HandleExceptionAsync(context,ex);
}
}
private Task HandleExceptionAsync(HttpContext context,Exception exception)
{
ApiError error = _options.AddResponseDetails?.Invoke(exception)
?? ApiErrorFactory.New(exception);
LogApiException(exception,error);
return CreateResponse(context,error);
}
private static Task CreateResponse(HttpContext context,ApiError error)
{
var result = JsonSerializer.Serialize(error,new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,});
context.Response.ContentType = "application/json";
context.Response.StatusCode = (int)error.Status;
return context.Response.WriteAsync(result);
}
private void LogApiException(Exception exception,ApiError error)
{
var innerExMessage = GetInnermostExceptionMessage(exception);
var level = _options.DetermineLogLevel?.Invoke(exception) ?? GetLogLevel(exception);
_logger.Log(level,exception,"ERROR: {message} -- {ErrorId}.",innerExMessage,error.Id);
}
private static LogLevel GetLogLevel(Exception exception) =>
exception switch
{
InvalidInputException _ => LogLevel.Warning,_ => LogLevel.Error
};
private string GetInnermostExceptionMessage(Exception exception)
{
if (exception.InnerException != null)
return GetInnermostExceptionMessage(exception.InnerException);
return exception.Message;
}
}
public class ApiExceptionOptions
{
public Func<Exception,ApiError> AddResponseDetails { get; set; }
public Func<Exception,LogLevel> DetermineLogLevel { get; set; }
}
public static class ApiErrorFactory
{
public static ApiError New(Exception exception) =>
exception switch
{
InvalidInputException e => new ApiError
{
Details = e.Details,Message = e.Message,Status = BadRequest
},_ => new ApiError()
};
}
public class ApiError
{
public static string DefaultErrorMessage = "Erro no processamento da requisição.";
public string Id { get; } = Guid.NewGuid().ToString();
public HttpStatusCode Status { get; set; } = HttpStatusCode.InternalServerError;
public string Title { get; set; } = "API Error";
public string Message { get; set; } = DefaultErrorMessage;
public IDictionary<string,object> Details { get; set; } = new Dictionary<string,object>();
}
public static class ApiExceptionExtensions
{
public static IApplicationBuilder UseApiExceptionHandler(this IApplicationBuilder builder)
{
var options = new ApiExceptionOptions();
return builder.UseMiddleware<ApiException>(options);
}
public static IApplicationBuilder UseApiExceptionHandler(this IApplicationBuilder builder,Action<ApiExceptionOptions> configureOptions)
{
var options = new ApiExceptionOptions();
configureOptions(options);
return builder.UseMiddleware<ApiException>(options);
}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)