From 1c2fea18dd08e1701d77d304bda2763319333e7b Mon Sep 17 00:00:00 2001 From: WangJunZzz <510423039@qq.com> Date: Thu, 28 Jul 2022 21:20:22 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=91=20=E7=BB=9F=E4=B8=80=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E8=BF=94=E5=9B=9E=E5=80=BC=E8=BF=87=E6=BB=A4=E5=99=A8?= =?UTF-8?q?=EF=BC=8C=E7=A9=BA=E6=8C=87=E9=92=88=E5=BC=82=E5=B8=B8=20#61?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Customs/Dtos/WrapResult.cs | 8 +- .../MVC/Filters/ResultExceptionFilter.cs | 128 +++++++++--------- ...ttribute.cs => DontWrapResultAttribute.cs} | 2 +- .../Lion.AbpPro.HttpApi.Host/GlobalUsings.cs | 3 +- 4 files changed, 70 insertions(+), 71 deletions(-) rename aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/Extensions/System/{WrapResultAttribute.cs => DontWrapResultAttribute.cs} (51%) diff --git a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/Customs/Dtos/WrapResult.cs b/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/Customs/Dtos/WrapResult.cs index 9a1b7e20..04b34b1a 100644 --- a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/Customs/Dtos/WrapResult.cs +++ b/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/Customs/Dtos/WrapResult.cs @@ -2,13 +2,13 @@ { public class WrapResult { - private bool Success { get; set; } + public bool Success { get; set; } - private string Message { get; set; } + public string Message { get; set; } - private T Data { get; set; } + public T Data { get; set; } - private int Code { get; set; } + public int Code { get; set; } public WrapResult() { diff --git a/aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/Extensions/MVC/Filters/ResultExceptionFilter.cs b/aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/Extensions/MVC/Filters/ResultExceptionFilter.cs index 87f1b3e7..bffd8ccb 100644 --- a/aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/Extensions/MVC/Filters/ResultExceptionFilter.cs +++ b/aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/Extensions/MVC/Filters/ResultExceptionFilter.cs @@ -1,27 +1,7 @@ -namespace Lion.AbpPro.Shared.Hosting.Microservices.Microsoft.AspNetCore.MVC.Filters +namespace Lion.AbpPro.Extensions.MVC.Filters { - public sealed class ResultExceptionFilter : IFilterMetadata, IAsyncExceptionFilter, ITransientDependency + public sealed class ResultExceptionFilter : IAsyncExceptionFilter, ITransientDependency { - private ILogger Logger { get; set; } - - private readonly IExceptionToErrorInfoConverter _errorInfoConverter; - private readonly IHttpExceptionStatusCodeFinder _statusCodeFinder; - private readonly IJsonSerializer _jsonSerializer; - private readonly AbpExceptionHandlingOptions _exceptionHandlingOptions; - - public ResultExceptionFilter( - IExceptionToErrorInfoConverter errorInfoConverter, - IHttpExceptionStatusCodeFinder statusCodeFinder, - IJsonSerializer jsonSerializer, - IOptions exceptionHandlingOptions) - { - _errorInfoConverter = errorInfoConverter; - _statusCodeFinder = statusCodeFinder; - _jsonSerializer = jsonSerializer; - _exceptionHandlingOptions = exceptionHandlingOptions.Value; - Logger = NullLogger.Instance; - } - public async Task OnExceptionAsync(ExceptionContext context) { if (!ShouldHandleException(context)) @@ -29,78 +9,96 @@ namespace Lion.AbpPro.Shared.Hosting.Microservices.Microsoft.AspNetCore.MVC.Filt return; } - await HandleAndWrapException(context); } private bool ShouldHandleException(ExceptionContext context) { - if (context.ActionDescriptor.AsControllerActionDescriptor().ControllerTypeInfo.GetCustomAttributes(typeof(WrapResultAttribute), true).Any()) + if (context.ActionDescriptor.AsControllerActionDescriptor().ControllerTypeInfo.GetCustomAttributes(typeof(DontWrapResultAttribute), true).Any()) { return true; } - if (context.ActionDescriptor.GetMethodInfo().GetCustomAttributes(typeof(WrapResultAttribute), true).Any()) + if (context.ActionDescriptor.GetMethodInfo().GetCustomAttributes(typeof(DontWrapResultAttribute), true).Any()) { return true; } - + return false; } private async Task HandleAndWrapException(ExceptionContext context) { - //TODO: Trigger an AbpExceptionHandled event or something like that. - - context.HttpContext.Response.Headers.Add(AbpHttpConsts.AbpErrorFormat, "true"); - var statusCode = (int)_statusCodeFinder.GetStatusCode(context.HttpContext, context.Exception); - context.HttpContext.Response.StatusCode = 200; - - var remoteServiceErrorInfo = _errorInfoConverter.Convert(context.Exception, options => { options.SendExceptionsDetailsToClients = _exceptionHandlingOptions.SendExceptionsDetailsToClients; }); - remoteServiceErrorInfo.Code = context.HttpContext.TraceIdentifier; - remoteServiceErrorInfo.Message = SimplifyMessage(context.Exception); - var result = new WrapResult(); - result.SetFail(remoteServiceErrorInfo.Message); - - // HttpResponse - context.Result = new ObjectResult(result); + var exceptionHandlingOptions = context.GetRequiredService>().Value; + var exceptionToErrorInfoConverter = context.GetRequiredService(); + var remoteServiceErrorInfo = exceptionToErrorInfoConverter.Convert(context.Exception, options => + { + options.SendExceptionsDetailsToClients = exceptionHandlingOptions.SendExceptionsDetailsToClients; + options.SendStackTraceToClients = exceptionHandlingOptions.SendStackTraceToClients; + }); - // 写日志 var logLevel = context.Exception.GetLogLevel(); + var remoteServiceErrorInfoBuilder = new StringBuilder(); remoteServiceErrorInfoBuilder.AppendLine($"---------- {nameof(RemoteServiceErrorInfo)} ----------"); - remoteServiceErrorInfoBuilder.AppendLine(_jsonSerializer.Serialize(remoteServiceErrorInfo, indented: true)); - Logger.LogWithLevel(logLevel, remoteServiceErrorInfoBuilder.ToString()); - Logger.LogException(context.Exception, logLevel); + remoteServiceErrorInfoBuilder.AppendLine(context.GetRequiredService().Serialize(remoteServiceErrorInfo, indented: true)); + + var logger = context.GetService>(NullLogger.Instance); + + logger.LogWithLevel(logLevel, remoteServiceErrorInfoBuilder.ToString()); - await context.HttpContext - .RequestServices - .GetRequiredService() - .NotifyAsync( - new ExceptionNotificationContext(context.Exception) - ); + logger.LogException(context.Exception, logLevel); + await context.GetRequiredService().NotifyAsync(new ExceptionNotificationContext(context.Exception)); + context.HttpContext.Response.StatusCode = 200; + var result = SimplifyMessage(context); + context.Result = new ObjectResult(result); context.Exception = null; //Handled! } - private string SimplifyMessage(Exception error) + private WrapResult SimplifyMessage(ExceptionContext context) { - switch (error) + var result = new WrapResult(); + var localizer = context.GetService>(); + switch (context.Exception) { - case AbpAuthorizationException e: - return "Authenticate failure!"; - case AbpValidationException e: - return "Request param validate failure!"; - case EntityNotFoundException e: - return "not found the entity!"; - case BusinessException e: - return $"{e.Message}"; - case NotImplementedException e: - return "not implement!"; + case AbpAuthorizationException: + result.Code = 401; + result.Message = "权限不足."; + break; + case AbpValidationException: + result.Code = 400; + result.Message = "请求参数验证失败."; + break; + case EntityNotFoundException: + result.Code = 506; + result.Message = "实体不存在."; + break; + case NotImplementedException: + result.Code = 507; + result.Message = "未实现功能."; + break; default: - return "server internal error!"; + { + result.Code = 500; + if (context.Exception is IHasErrorCode codeException) + { + result.Message = localizer[codeException.Code]; + foreach (var key in context.Exception.Data.Keys) + { + result.Message = result.Message.Replace("{" + key + "}", context.Exception.Data[key]?.ToString()); + } + } + else + { + result.Message = context.Exception.Message; + } + + break; + } } + + return result; } } - -} +} \ No newline at end of file diff --git a/aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/Extensions/System/WrapResultAttribute.cs b/aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/Extensions/System/DontWrapResultAttribute.cs similarity index 51% rename from aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/Extensions/System/WrapResultAttribute.cs rename to aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/Extensions/System/DontWrapResultAttribute.cs index aa3a4ad5..32cb31e5 100644 --- a/aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/Extensions/System/WrapResultAttribute.cs +++ b/aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/Extensions/System/DontWrapResultAttribute.cs @@ -1,6 +1,6 @@ namespace Lion.AbpPro.Extensions.System { - public class WrapResultAttribute : Attribute + public class DontWrapResultAttribute : Attribute { } } \ No newline at end of file diff --git a/aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/GlobalUsings.cs b/aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/GlobalUsings.cs index 1218a030..b7c338a6 100644 --- a/aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/GlobalUsings.cs +++ b/aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/GlobalUsings.cs @@ -20,12 +20,12 @@ global using Lion.AbpPro.Extension.Customs.Dtos; global using Lion.AbpPro.Extensions; global using Lion.AbpPro.Extensions.Hangfire; global using Lion.AbpPro.Extensions.Middlewares; +global using Lion.AbpPro.Extensions.MVC.Filters; global using Lion.AbpPro.Extensions.System; global using Lion.AbpPro.Localization; global using Lion.AbpPro.MultiTenancy; global using Lion.AbpPro.Shared.Hosting.Microservices; global using Lion.AbpPro.Shared.Hosting.Microservices.Microsoft.AspNetCore.Builder; -global using Lion.AbpPro.Shared.Hosting.Microservices.Microsoft.AspNetCore.MVC.Filters; global using Lion.AbpPro.Shared.Hosting.Microservices.Swaggers; global using Magicodes.ExporterAndImporter.Core; global using Magicodes.ExporterAndImporter.Excel; @@ -41,6 +41,7 @@ global using Microsoft.AspNetCore.Mvc.Filters; global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.Hosting; +global using Microsoft.Extensions.Localization; global using Microsoft.Extensions.Logging; global using Microsoft.Extensions.Logging.Abstractions; global using Microsoft.Extensions.Options;