using Microsoft.AspNetCore.Http; using System.Buffers; namespace YLErp.Web.App { /// /// 异常处理中间件 /// internal class ExceptionMiddleware { private readonly RequestDelegate _next; public ExceptionMiddleware(RequestDelegate next) { _next = next; } public async Task Invoke(HttpContext context) { try { await _next.Invoke(context); } catch (Exception ex) { await HandleExceptionMessageAsync(context, ex); } } private static async Task HandleExceptionMessageAsync(HttpContext context, Exception exception) { var message = string.Empty; var serviceExpcetion = exception as ServiceException; var request = context.Request; try { message = GetInnerExceptionMessage(exception); if (serviceExpcetion == null || serviceExpcetion.IsFaultError) { var result = await request.BodyReader.ReadAsync(); var reqBody = ConvertBufferToString(result.Buffer); LogFactory.GetLogger(context.Request.Path.Value).Error(serviceExpcetion ?? exception, $"[query]:{request.QueryString.Value};[body]:{reqBody}"); } } catch (Exception ex) { message += "\r\n\r\n" + ex.Message; } if (request.Path.StartsWithSegments("/m/api", StringComparison.OrdinalIgnoreCase) || request.Headers["X-Requested-With"] == "XMLHttpRequest" && !request.Headers["Accept"].Contains("text/html")) { await context.Response.WriteAsJsonAsync(new { code = -1, success = false, msg = message, Data = serviceExpcetion?.Tag }); } else { context.Response.ContentType = "text/html"; var resultHtml = File.ReadAllText(Server.MapPath("Statics/html/ShowError.html")); resultHtml = resultHtml.Replace("{{ErrorMsg}}", message); await context.Response.WriteAsync(resultHtml); } } private static string ConvertBufferToString(in ReadOnlySequence readOnlySequence) { // Separate method because Span/ReadOnlySpan cannot be used in async methods ReadOnlySpan span = readOnlySequence.IsSingleSegment ? readOnlySequence.First.Span : readOnlySequence.ToArray().AsSpan(); return System.Text.Encoding.UTF8.GetString(span); } private static string GetInnerExceptionMessage(Exception ex) { var exceptionStr = ex.Message; while (ex.InnerException != null) { exceptionStr = ex.InnerException.Message; ex = ex.InnerException; } return exceptionStr; } } }