diff --git a/framework/Volo.Abp.sln b/framework/Volo.Abp.sln index 19fbf05df8..ca1a85fd8d 100644 --- a/framework/Volo.Abp.sln +++ b/framework/Volo.Abp.sln @@ -471,6 +471,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.BlobStoring.Google EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.BlobStoring.Google.Tests", "test\Volo.Abp.BlobStoring.Google.Tests\Volo.Abp.BlobStoring.Google.Tests.csproj", "{40FB8907-9CF7-44D0-8B5F-538AC6DAF8B9}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.ExceptionHandling.Tests", "test\Volo.Abp.ExceptionHandling.Tests\Volo.Abp.ExceptionHandling.Tests.csproj", "{E50739A7-5E2F-4EB5-AEA9-554115CB9613}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -1405,6 +1407,10 @@ Global {40FB8907-9CF7-44D0-8B5F-538AC6DAF8B9}.Debug|Any CPU.Build.0 = Debug|Any CPU {40FB8907-9CF7-44D0-8B5F-538AC6DAF8B9}.Release|Any CPU.ActiveCfg = Release|Any CPU {40FB8907-9CF7-44D0-8B5F-538AC6DAF8B9}.Release|Any CPU.Build.0 = Release|Any CPU + {E50739A7-5E2F-4EB5-AEA9-554115CB9613}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E50739A7-5E2F-4EB5-AEA9-554115CB9613}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E50739A7-5E2F-4EB5-AEA9-554115CB9613}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E50739A7-5E2F-4EB5-AEA9-554115CB9613}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1642,6 +1648,7 @@ Global {E1051CD0-9262-4869-832D-B951723F4DDE} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {DEEB5200-BBF9-464D-9B7E-8FC035A27E94} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {40FB8907-9CF7-44D0-8B5F-538AC6DAF8B9} = {447C8A77-E5F0-4538-8687-7383196D04EA} + {E50739A7-5E2F-4EB5-AEA9-554115CB9613} = {447C8A77-E5F0-4538-8687-7383196D04EA} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {BB97ECF4-9A84-433F-A80B-2A3285BDD1D5} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/ExceptionHandling/UserExceptionInformer.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/ExceptionHandling/UserExceptionInformer.cs index 6773e4ff37..a8b0f71dea 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/ExceptionHandling/UserExceptionInformer.cs +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/ExceptionHandling/UserExceptionInformer.cs @@ -67,6 +67,7 @@ public class UserExceptionInformer : IUserExceptionInformer, IScopedDependency { options.SendExceptionsDetailsToClients = Options.SendExceptionsDetailsToClients; options.SendStackTraceToClients = Options.SendStackTraceToClients; + options.SendExceptionDataToClientTypes = Options.SendExceptionDataToClientTypes; }); } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Controllers/ErrorController.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Controllers/ErrorController.cs index e38995a685..e9800c8788 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Controllers/ErrorController.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Controllers/ErrorController.cs @@ -51,6 +51,7 @@ public class ErrorController : AbpController { options.SendExceptionsDetailsToClients = ExceptionHandlingOptions.SendExceptionsDetailsToClients; options.SendStackTraceToClients = ExceptionHandlingOptions.SendStackTraceToClients; + options.SendExceptionDataToClientTypes = ExceptionHandlingOptions.SendExceptionDataToClientTypes; }); if (httpStatusCode == 0) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionFilter.cs index 3b60e74d78..03684b063d 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionFilter.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionFilter.cs @@ -102,6 +102,7 @@ public class AbpExceptionFilter : IAsyncExceptionFilter, IAbpFilter, ITransientD { options.SendExceptionsDetailsToClients = exceptionHandlingOptions.SendExceptionsDetailsToClients; options.SendStackTraceToClients = exceptionHandlingOptions.SendStackTraceToClients; + options.SendExceptionDataToClientTypes = exceptionHandlingOptions.SendExceptionDataToClientTypes; }); var remoteServiceErrorInfoBuilder = new StringBuilder(); diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionPageFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionPageFilter.cs index 56814718b6..8869293c7a 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionPageFilter.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionPageFilter.cs @@ -81,6 +81,7 @@ public class AbpExceptionPageFilter : IAsyncPageFilter, IAbpFilter, ITransientDe { options.SendExceptionsDetailsToClients = exceptionHandlingOptions.SendExceptionsDetailsToClients; options.SendStackTraceToClients = exceptionHandlingOptions.SendStackTraceToClients; + options.SendExceptionDataToClientTypes = exceptionHandlingOptions.SendExceptionDataToClientTypes; }); var logLevel = context.Exception!.GetLogLevel(); diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/ExceptionHandling/AbpExceptionHandlingMiddleware.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/ExceptionHandling/AbpExceptionHandlingMiddleware.cs index 7d5ef610e5..e144812753 100644 --- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/ExceptionHandling/AbpExceptionHandlingMiddleware.cs +++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/ExceptionHandling/AbpExceptionHandlingMiddleware.cs @@ -92,6 +92,7 @@ public class AbpExceptionHandlingMiddleware : AbpMiddlewareBase, ITransientDepen { options.SendExceptionsDetailsToClients = exceptionHandlingOptions.SendExceptionsDetailsToClients; options.SendStackTraceToClients = exceptionHandlingOptions.SendStackTraceToClients; + options.SendExceptionDataToClientTypes = exceptionHandlingOptions.SendExceptionDataToClientTypes; }) ) ) diff --git a/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/AspNetCore/ExceptionHandling/AbpExceptionHandlingOptions.cs b/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/AspNetCore/ExceptionHandling/AbpExceptionHandlingOptions.cs index 1905c70e69..e3bde2e813 100644 --- a/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/AspNetCore/ExceptionHandling/AbpExceptionHandlingOptions.cs +++ b/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/AspNetCore/ExceptionHandling/AbpExceptionHandlingOptions.cs @@ -1,8 +1,23 @@ -namespace Volo.Abp.AspNetCore.ExceptionHandling; +using System; +using System.Collections.Generic; + +namespace Volo.Abp.AspNetCore.ExceptionHandling; public class AbpExceptionHandlingOptions { - public bool SendExceptionsDetailsToClients { get; set; } = false; + public bool SendExceptionsDetailsToClients { get; set; } + + public bool SendStackTraceToClients { get; set; } + + public List SendExceptionDataToClientTypes { get; set; } - public bool SendStackTraceToClients { get; set; } = true; + public AbpExceptionHandlingOptions() + { + SendExceptionsDetailsToClients = false; + SendStackTraceToClients = true; + SendExceptionDataToClientTypes = + [ + typeof(IBusinessException) + ]; + } } diff --git a/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/AspNetCore/ExceptionHandling/DefaultExceptionToErrorInfoConverter.cs b/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/AspNetCore/ExceptionHandling/DefaultExceptionToErrorInfoConverter.cs index 82ed962a4f..63d6aa82ad 100644 --- a/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/AspNetCore/ExceptionHandling/DefaultExceptionToErrorInfoConverter.cs +++ b/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/AspNetCore/ExceptionHandling/DefaultExceptionToErrorInfoConverter.cs @@ -132,7 +132,10 @@ public class DefaultExceptionToErrorInfoConverter : IExceptionToErrorInfoConvert errorInfo.Message = L["InternalServerErrorMessage"]; } - errorInfo.Data = exception.Data; + if (options.SendExceptionDataToClientTypes.Any(t => t.IsInstanceOfType(exception))) + { + errorInfo.Data = exception.Data; + } return errorInfo; } diff --git a/framework/test/Volo.Abp.ExceptionHandling.Tests/Volo.Abp.ExceptionHandling.Tests.csproj b/framework/test/Volo.Abp.ExceptionHandling.Tests/Volo.Abp.ExceptionHandling.Tests.csproj new file mode 100644 index 0000000000..0c56c7190c --- /dev/null +++ b/framework/test/Volo.Abp.ExceptionHandling.Tests/Volo.Abp.ExceptionHandling.Tests.csproj @@ -0,0 +1,17 @@ + + + + + + net8.0 + + + + + + + + + + + diff --git a/framework/test/Volo.Abp.ExceptionHandling.Tests/Volo/Abp/ExceptionHandling/AbpExceptionHandlingTestBase.cs b/framework/test/Volo.Abp.ExceptionHandling.Tests/Volo/Abp/ExceptionHandling/AbpExceptionHandlingTestBase.cs new file mode 100644 index 0000000000..aa384cf782 --- /dev/null +++ b/framework/test/Volo.Abp.ExceptionHandling.Tests/Volo/Abp/ExceptionHandling/AbpExceptionHandlingTestBase.cs @@ -0,0 +1,11 @@ +using Volo.Abp.Testing; + +namespace Volo.Abp.ExceptionHandling; + +public class AbpExceptionHandlingTestBase : AbpIntegratedTest +{ + protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) + { + options.UseAutofac(); + } +} diff --git a/framework/test/Volo.Abp.ExceptionHandling.Tests/Volo/Abp/ExceptionHandling/AbpExceptionHandlingTestModule.cs b/framework/test/Volo.Abp.ExceptionHandling.Tests/Volo/Abp/ExceptionHandling/AbpExceptionHandlingTestModule.cs new file mode 100644 index 0000000000..4f19b0bcfe --- /dev/null +++ b/framework/test/Volo.Abp.ExceptionHandling.Tests/Volo/Abp/ExceptionHandling/AbpExceptionHandlingTestModule.cs @@ -0,0 +1,14 @@ +using Volo.Abp.Autofac; +using Volo.Abp.Modularity; + +namespace Volo.Abp.ExceptionHandling; + +[DependsOn( + typeof(AbpExceptionHandlingModule), + typeof(AbpTestBaseModule), + typeof(AbpAutofacModule) + )] +public class AbpExceptionHandlingTestModule : AbpModule +{ + +} diff --git a/framework/test/Volo.Abp.ExceptionHandling.Tests/Volo/Abp/ExceptionHandling/ExceptionToErrorInfoConverter_Tests.cs b/framework/test/Volo.Abp.ExceptionHandling.Tests/Volo/Abp/ExceptionHandling/ExceptionToErrorInfoConverter_Tests.cs new file mode 100644 index 0000000000..7ca93d7ee9 --- /dev/null +++ b/framework/test/Volo.Abp.ExceptionHandling.Tests/Volo/Abp/ExceptionHandling/ExceptionToErrorInfoConverter_Tests.cs @@ -0,0 +1,53 @@ +using Shouldly; +using Volo.Abp.AspNetCore.ExceptionHandling; +using Xunit; + +namespace Volo.Abp.ExceptionHandling; + +public class ExceptionToErrorInfoConverter_Tests : AbpExceptionHandlingTestBase +{ + private readonly IExceptionToErrorInfoConverter _exceptionToErrorInfoConverter; + + public ExceptionToErrorInfoConverter_Tests() + { + _exceptionToErrorInfoConverter = GetRequiredService(); + } + + [Fact] + public void SendExceptionDataToClientTypes_Test() + { + var exception = new AbpException("test message") + { + Data = + { + ["my_data"] = "my_data_value", + ["my_data2"] = 42 + } + }; + var errorInfo = _exceptionToErrorInfoConverter.Convert(exception); + errorInfo.Data.ShouldBeNull(); + + errorInfo = _exceptionToErrorInfoConverter.Convert(exception, options => + { + options.SendExceptionDataToClientTypes.Add(typeof(AbpException)); + }); + errorInfo.Data.ShouldNotBeNull(); + errorInfo.Data.Keys.Count.ShouldBe(2); + errorInfo.Data["my_data"].ShouldBe("my_data_value"); + errorInfo.Data["my_data2"].ShouldBe(42); + + var businessException = new BusinessException("test message") + { + Data = + { + ["my_data"] = "my_data_value", + ["my_data2"] = 42 + } + }; + errorInfo = _exceptionToErrorInfoConverter.Convert(businessException); + errorInfo.Data.ShouldNotBeNull(); + errorInfo.Data.Keys.Count.ShouldBe(2); + errorInfo.Data["my_data"].ShouldBe("my_data_value"); + errorInfo.Data["my_data2"].ShouldBe(42); + } +} diff --git a/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/AuditLogInfoToAuditLogConverter.cs b/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/AuditLogInfoToAuditLogConverter.cs index fccc5b65fe..94f0622714 100644 --- a/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/AuditLogInfoToAuditLogConverter.cs +++ b/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/AuditLogInfoToAuditLogConverter.cs @@ -57,6 +57,7 @@ public class AuditLogInfoToAuditLogConverter : IAuditLogInfoToAuditLogConverter, { options.SendExceptionsDetailsToClients = ExceptionHandlingOptions.SendExceptionsDetailsToClients; options.SendStackTraceToClients = ExceptionHandlingOptions.SendStackTraceToClients; + options.SendExceptionDataToClientTypes = ExceptionHandlingOptions.SendExceptionDataToClientTypes; })) ?? new List();