Add an option to AbpExceptionHandlingOptions for enabling/disabling stacktrace

pull/10594/head
Berkan Sasmaz 4 years ago
parent 6051fd4e38
commit d153bfea1b

@ -63,7 +63,11 @@ namespace Volo.Abp.AspNetCore.Components.Web.ExceptionHandling
protected virtual RemoteServiceErrorInfo GetErrorInfo(UserExceptionInformerContext context)
{
return ExceptionToErrorInfoConverter.Convert(context.Exception, Options.SendExceptionsDetailsToClients);
return ExceptionToErrorInfoConverter.Convert(context.Exception, options =>
{
options.SendExceptionsDetailsToClients = Options.SendExceptionsDetailsToClients;
options.EnableStackTrace = Options.EnableStackTrace;
});
}
}
}

@ -47,7 +47,11 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Controllers
await _exceptionNotifier.NotifyAsync(new ExceptionNotificationContext(exception));
var errorInfo = _errorInfoConverter.Convert(exception, _exceptionHandlingOptions.SendExceptionsDetailsToClients);
var errorInfo = _errorInfoConverter.Convert(exception, options =>
{
options.SendExceptionsDetailsToClients = _exceptionHandlingOptions.SendExceptionsDetailsToClients;
options.EnableStackTrace = _exceptionHandlingOptions.EnableStackTrace;
});
if (httpStatusCode == 0)
{

@ -59,7 +59,11 @@ namespace Volo.Abp.AspNetCore.Mvc.ExceptionHandling
var exceptionHandlingOptions = context.GetRequiredService<IOptions<AbpExceptionHandlingOptions>>().Value;
var exceptionToErrorInfoConverter = context.GetRequiredService<IExceptionToErrorInfoConverter>();
var remoteServiceErrorInfo = exceptionToErrorInfoConverter.Convert(context.Exception, exceptionHandlingOptions.SendExceptionsDetailsToClients);
var remoteServiceErrorInfo = exceptionToErrorInfoConverter.Convert(context.Exception, options =>
{
options.SendExceptionsDetailsToClients = exceptionHandlingOptions.SendExceptionsDetailsToClients;
options.EnableStackTrace = exceptionHandlingOptions.EnableStackTrace;
});
var logLevel = context.Exception.GetLogLevel();

@ -71,7 +71,11 @@ namespace Volo.Abp.AspNetCore.Mvc.ExceptionHandling
var exceptionHandlingOptions = context.GetRequiredService<IOptions<AbpExceptionHandlingOptions>>().Value;
var exceptionToErrorInfoConverter = context.GetRequiredService<IExceptionToErrorInfoConverter>();
var remoteServiceErrorInfo = exceptionToErrorInfoConverter.Convert(context.Exception, exceptionHandlingOptions.SendExceptionsDetailsToClients);
var remoteServiceErrorInfo = exceptionToErrorInfoConverter.Convert(context.Exception, options =>
{
options.SendExceptionsDetailsToClients = exceptionHandlingOptions.SendExceptionsDetailsToClients;
options.EnableStackTrace = exceptionHandlingOptions.EnableStackTrace;
});
var logLevel = context.Exception.GetLogLevel();

@ -76,7 +76,7 @@ namespace Volo.Abp.AspNetCore.ExceptionHandling
var errorInfoConverter = httpContext.RequestServices.GetRequiredService<IExceptionToErrorInfoConverter>();
var statusCodeFinder = httpContext.RequestServices.GetRequiredService<IHttpExceptionStatusCodeFinder>();
var jsonSerializer = httpContext.RequestServices.GetRequiredService<IJsonSerializer>();
var options = httpContext.RequestServices.GetRequiredService<IOptions<AbpExceptionHandlingOptions>>().Value;
var exceptionHandlingOptions = httpContext.RequestServices.GetRequiredService<IOptions<AbpExceptionHandlingOptions>>().Value;
httpContext.Response.Clear();
httpContext.Response.StatusCode = (int)statusCodeFinder.GetStatusCode(httpContext, exception);
@ -86,7 +86,11 @@ namespace Volo.Abp.AspNetCore.ExceptionHandling
await httpContext.Response.WriteAsync(
jsonSerializer.Serialize(
new RemoteServiceErrorResponse(
errorInfoConverter.Convert(exception, options.SendExceptionsDetailsToClients)
errorInfoConverter.Convert(exception, options =>
{
options.SendExceptionsDetailsToClients = exceptionHandlingOptions.SendExceptionsDetailsToClients;
options.EnableStackTrace = exceptionHandlingOptions.EnableStackTrace;
})
)
)
);

@ -2,6 +2,21 @@
{
public class AbpExceptionHandlingOptions
{
public bool SendExceptionsDetailsToClients { get; set; } = false;
public bool SendExceptionsDetailsToClients { get; set; }
private bool _enableStackTrace;
public bool EnableStackTrace
{
get => _enableStackTrace;
set
{
_enableStackTrace = value;
if (_enableStackTrace)
{
SendExceptionsDetailsToClients = true;
}
}
}
}
}

@ -40,7 +40,11 @@ namespace Volo.Abp.AspNetCore.ExceptionHandling
public RemoteServiceErrorInfo Convert(Exception exception, bool includeSensitiveDetails)
{
var errorInfo = CreateErrorInfoWithoutCode(exception, includeSensitiveDetails);
var exceptionHandlingOptions = CreateDefaultOptions();
exceptionHandlingOptions.SendExceptionsDetailsToClients = includeSensitiveDetails;
exceptionHandlingOptions.EnableStackTrace = includeSensitiveDetails;
var errorInfo = CreateErrorInfoWithoutCode(exception, exceptionHandlingOptions);
if (exception is IHasErrorCode hasErrorCodeException)
{
@ -50,11 +54,26 @@ namespace Volo.Abp.AspNetCore.ExceptionHandling
return errorInfo;
}
protected virtual RemoteServiceErrorInfo CreateErrorInfoWithoutCode(Exception exception, bool includeSensitiveDetails)
public RemoteServiceErrorInfo Convert(Exception exception, Action<AbpExceptionHandlingOptions> options = null)
{
if (includeSensitiveDetails)
var exceptionHandlingOptions = CreateDefaultOptions();
options?.Invoke(exceptionHandlingOptions);
var errorInfo = CreateErrorInfoWithoutCode(exception, exceptionHandlingOptions);
if (exception is IHasErrorCode hasErrorCodeException)
{
errorInfo.Code = hasErrorCodeException.Code;
}
return errorInfo;
}
protected virtual RemoteServiceErrorInfo CreateErrorInfoWithoutCode(Exception exception, AbpExceptionHandlingOptions options)
{
if (options.SendExceptionsDetailsToClients)
{
return CreateDetailedErrorInfoFromException(exception);
return CreateDetailedErrorInfoFromException(exception, options.EnableStackTrace);
}
exception = TryToGetActualException(exception);
@ -194,11 +213,11 @@ namespace Volo.Abp.AspNetCore.ExceptionHandling
return exception;
}
protected virtual RemoteServiceErrorInfo CreateDetailedErrorInfoFromException(Exception exception)
protected virtual RemoteServiceErrorInfo CreateDetailedErrorInfoFromException(Exception exception, bool enableStackTrace)
{
var detailBuilder = new StringBuilder();
AddExceptionToDetails(exception, detailBuilder);
AddExceptionToDetails(exception, detailBuilder, enableStackTrace);
var errorInfo = new RemoteServiceErrorInfo(exception.Message, detailBuilder.ToString());
@ -210,7 +229,7 @@ namespace Volo.Abp.AspNetCore.ExceptionHandling
return errorInfo;
}
protected virtual void AddExceptionToDetails(Exception exception, StringBuilder detailBuilder)
protected virtual void AddExceptionToDetails(Exception exception, StringBuilder detailBuilder, bool enableStackTrace)
{
//Exception Message
detailBuilder.AppendLine(exception.GetType().Name + ": " + exception.Message);
@ -237,7 +256,7 @@ namespace Volo.Abp.AspNetCore.ExceptionHandling
}
//Exception StackTrace
if (!string.IsNullOrEmpty(exception.StackTrace))
if (enableStackTrace && !string.IsNullOrEmpty(exception.StackTrace))
{
detailBuilder.AppendLine("STACK TRACE: " + exception.StackTrace);
}
@ -245,7 +264,7 @@ namespace Volo.Abp.AspNetCore.ExceptionHandling
//Inner exception
if (exception.InnerException != null)
{
AddExceptionToDetails(exception.InnerException, detailBuilder);
AddExceptionToDetails(exception.InnerException, detailBuilder, enableStackTrace);
}
//Inner exceptions for AggregateException
@ -259,7 +278,7 @@ namespace Volo.Abp.AspNetCore.ExceptionHandling
foreach (var innerException in aggException.InnerExceptions)
{
AddExceptionToDetails(innerException, detailBuilder);
AddExceptionToDetails(innerException, detailBuilder, enableStackTrace);
}
}
}
@ -296,5 +315,14 @@ namespace Volo.Abp.AspNetCore.ExceptionHandling
return detailBuilder.ToString();
}
protected virtual AbpExceptionHandlingOptions CreateDefaultOptions()
{
return new AbpExceptionHandlingOptions
{
SendExceptionsDetailsToClients = false,
EnableStackTrace = false
};
}
}
}

@ -12,9 +12,18 @@ namespace Volo.Abp.AspNetCore.ExceptionHandling
/// <summary>
/// Converter method.
/// </summary>
/// <param name="exception">The exception</param>
/// <param name="exception">The exception.</param>
/// <param name="includeSensitiveDetails">Should include sensitive details to the error info?</param>
/// <returns>Error info or null</returns>
[Obsolete("Use other Convert method.")]
RemoteServiceErrorInfo Convert(Exception exception, bool includeSensitiveDetails);
/// <summary>
/// Converter method.
/// </summary>
/// <param name="exception">The exception.</param>
/// <param name="options">Additional options.</param>
/// <returns>Error info or null</returns>
RemoteServiceErrorInfo Convert(Exception exception, Action<AbpExceptionHandlingOptions> options = null);
}
}

@ -21,27 +21,27 @@ namespace Microsoft.AspNetCore.Authorization
using (CultureHelper.Use("zh-Hans"))
{
var exception = new AbpAuthorizationException(code: AbpAuthorizationErrorCodes.GivenPolicyHasNotGranted);
var errorInfo = _exceptionToErrorInfoConverter.Convert(exception, false);
var errorInfo = _exceptionToErrorInfoConverter.Convert(exception);
errorInfo.Message.ShouldBe("授权失败! 提供的策略尚未授予.");
exception = new AbpAuthorizationException(code: AbpAuthorizationErrorCodes.GivenPolicyHasNotGrantedWithPolicyName)
.WithData("PolicyName", "my_policy_name");
errorInfo = _exceptionToErrorInfoConverter.Convert(exception, false);
errorInfo = _exceptionToErrorInfoConverter.Convert(exception);
errorInfo.Message.ShouldBe("授权失败! 提供的策略尚未授予: my_policy_name");
exception = new AbpAuthorizationException(code: AbpAuthorizationErrorCodes.GivenPolicyHasNotGrantedForGivenResource)
.WithData("ResourceName", "my_resource_name");
errorInfo = _exceptionToErrorInfoConverter.Convert(exception, false);
errorInfo = _exceptionToErrorInfoConverter.Convert(exception);
errorInfo.Message.ShouldBe("授权失败! 提供的策略未授予提供的资源: my_resource_name");
exception = new AbpAuthorizationException(code: AbpAuthorizationErrorCodes.GivenRequirementHasNotGrantedForGivenResource)
.WithData("ResourceName", "my_resource_name");
errorInfo = _exceptionToErrorInfoConverter.Convert(exception, false);
errorInfo = _exceptionToErrorInfoConverter.Convert(exception);
errorInfo.Message.ShouldBe("授权失败! 提供的要求未授予提供的资源: my_resource_name");
exception = new AbpAuthorizationException(code: AbpAuthorizationErrorCodes.GivenRequirementsHasNotGrantedForGivenResource)
.WithData("ResourceName", "my_resource_name");
errorInfo = _exceptionToErrorInfoConverter.Convert(exception, false);
errorInfo = _exceptionToErrorInfoConverter.Convert(exception);
errorInfo.Message.ShouldBe("授权失败! 提供的要求未授予提供的资源: my_resource_name");
}
}

@ -22,17 +22,17 @@ namespace Volo.Abp.Features
{
var exception = new AbpAuthorizationException(code: AbpFeatureErrorCodes.FeatureIsNotEnabled)
.WithData("FeatureName", "my_feature_name");
var errorInfo = _exceptionToErrorInfoConverter.Convert(exception, false);
var errorInfo = _exceptionToErrorInfoConverter.Convert(exception);
errorInfo.Message.ShouldBe("功能未启用: my_feature_name");
exception = new AbpAuthorizationException(code: AbpFeatureErrorCodes.AllOfTheseFeaturesMustBeEnabled)
.WithData("FeatureNames", "my_feature_name, my_feature_name2");
errorInfo = _exceptionToErrorInfoConverter.Convert(exception, false);
errorInfo = _exceptionToErrorInfoConverter.Convert(exception);
errorInfo.Message.ShouldBe("必要的功能未启用. 这些功能需要启用: my_feature_name, my_feature_name2");
exception = new AbpAuthorizationException(code: AbpFeatureErrorCodes.AtLeastOneOfTheseFeaturesMustBeEnabled)
.WithData("FeatureNames", "my_feature_name, my_feature_name2");
errorInfo = _exceptionToErrorInfoConverter.Convert(exception, false);
errorInfo = _exceptionToErrorInfoConverter.Convert(exception);
errorInfo.Message.ShouldBe("必要的功能未启用. 需要启用这些功能中的一项my_feature_name, my_feature_name2");
}
}

@ -22,7 +22,7 @@ namespace Volo.Abp.GlobalFeatures
var exception = new AbpGlobalFeatureNotEnabledException(code: AbpGlobalFeatureErrorCodes.GlobalFeatureIsNotEnabled)
.WithData("ServiceName", "MyService")
.WithData("GlobalFeatureName", "TestFeature");;
var errorInfo = _exceptionToErrorInfoConverter.Convert(exception, false);
var errorInfo = _exceptionToErrorInfoConverter.Convert(exception);
errorInfo.Message.ShouldBe("'MyService'服务需要启用'TestFeature'功能.");
}
}

Loading…
Cancel
Save