diff --git a/HealthMonitor.WebApi/Middleware/LoggingMiddleware.cs b/HealthMonitor.WebApi/Middleware/LoggingMiddleware.cs index d562f30..c12cd55 100644 --- a/HealthMonitor.WebApi/Middleware/LoggingMiddleware.cs +++ b/HealthMonitor.WebApi/Middleware/LoggingMiddleware.cs @@ -1,5 +1,12 @@ using HealthMonitor.Common; +using HealthMonitor.WebApi.Controllers.Api; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Logging; using Newtonsoft.Json; +using System.IO; +using System.Net; +using System.Runtime.Serialization.Formatters.Binary; +using System.Text; namespace HealthMonitor.WebApi.Middleware { @@ -14,27 +21,54 @@ namespace HealthMonitor.WebApi.Middleware _logger = logger; } + //public async Task InvokeAsync(HttpContext context) + //{ + // //// 在请求处理之前记录日志 + // //using (_logger.BeginScope(new Dictionary { ["RequestId"] = "" })) + // using (new CustomizeStopWatch(nameof(LoggingMiddleware), _logger)) + // { + // var request = await FormatRequest(context.Request); + + // _logger.LogInformation(request); + + // var originalBodyStream = context.Response.Body; + + // using var responseBody = new MemoryStream(); + // context.Response.Body = responseBody; + + // await _next(context); + + // var response = await FormatResponse(context.Response); + + // _logger.LogInformation(response); + + // await responseBody.CopyToAsync(originalBodyStream); + // } + //} + public async Task InvokeAsync(HttpContext context) { //// 在请求处理之前记录日志 //using (_logger.BeginScope(new Dictionary { ["RequestId"] = "" })) using (new CustomizeStopWatch(nameof(LoggingMiddleware), _logger)) { - var request = await FormatRequest(context.Request); - - _logger.LogInformation(request); - - var originalBodyStream = context.Response.Body; - using var responseBody = new MemoryStream(); - context.Response.Body = responseBody; - - await _next(context); + var originalBodyStream = context.Response.Body; + try + { + + var request = await FormatRequest(context.Request); + _logger.LogInformation(request); + context.Response.Body = responseBody; + await _next(context); + } + catch (Exception ex) + { + await HandleExceptionAsync(context, ex); // 捕获异常了 在HandleExceptionAsync中处理 + } var response = await FormatResponse(context.Response); - _logger.LogInformation(response); - await responseBody.CopyToAsync(originalBodyStream); } } @@ -81,5 +115,62 @@ namespace HealthMonitor.WebApi.Middleware return json; } } + + private async Task HandleExceptionAsync(HttpContext context, Exception exception) + { + context.Response.ContentType = "application/json"; // 返回json 类型 + var response = context.Response; + + var errorResponse = new ErrorResponse + { + Success = false + }; // 自定义的异常错误信息类型 + switch (exception) + { + case ApplicationException ex: + if (ex.Message.Contains("Invalid token")) + { + response.StatusCode = (int)HttpStatusCode.Forbidden; + errorResponse.Message = ex.Message; + break; + } + response.StatusCode = (int)HttpStatusCode.BadRequest; + errorResponse.Message = ex.Message; + break; + case KeyNotFoundException ex: + response.StatusCode = (int)HttpStatusCode.NotFound; + errorResponse.Message = ex.Message; + break; + default: + response.StatusCode = (int)HttpStatusCode.InternalServerError; + errorResponse.Message = "Internal Server errors. Check Logs!"; + break; + } + //_logger.LogError(exception.Message); + //var result =JsonConvert.SerializeObject(ApiResponse.Fail(response.StatusCode, $"{exception.Message}")); + //await context.Response.WriteAsync(JsonConvert.SerializeObject(result)); + + // Create the error response using ApiResponse.Fail + var apiResponse = ApiResponse.Fail(response.StatusCode, $"{exception.Message}\n{exception.InnerException}\n{exception.StackTrace}"); + + // Convert the ApiResponse to JSON string + var resultJson = JsonConvert.SerializeObject(apiResponse); + + // Convert the JSON string to bytes using UTF-8 encoding + var resultBytes = Encoding.UTF8.GetBytes(resultJson); + + await response.Body.WriteAsync(resultBytes, 0, resultBytes.Length); + + var responseStr = await FormatResponse(context.Response); + + _logger.LogError(responseStr); + } + + internal class ErrorResponse + { + public bool Success { get; set; } + + public string Message { get; set; } = String.Empty; + } } }