diff --git a/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionFilter.cs b/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionFilter.cs index 0851543f10..15e65cc343 100644 --- a/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionFilter.cs +++ b/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionFilter.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Abstractions; @@ -8,6 +9,7 @@ using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Primitives; using Volo.Abp.DependencyInjection; using Volo.Abp.Http; +using Volo.Abp.Json; namespace Volo.Abp.AspNetCore.Mvc.ExceptionHandling { @@ -17,13 +19,16 @@ namespace Volo.Abp.AspNetCore.Mvc.ExceptionHandling private readonly IExceptionToErrorInfoConverter _errorInfoConverter; private readonly IHttpExceptionStatusCodeFinder _statusCodeFinder; + private readonly IJsonSerializer _jsonSerializer; public AbpExceptionFilter( IExceptionToErrorInfoConverter errorInfoConverter, - IHttpExceptionStatusCodeFinder statusCodeFinder) + IHttpExceptionStatusCodeFinder statusCodeFinder, + IJsonSerializer jsonSerializer) { _errorInfoConverter = errorInfoConverter; _statusCodeFinder = statusCodeFinder; + _jsonSerializer = jsonSerializer; Logger = NullLogger.Instance; } @@ -35,8 +40,6 @@ namespace Volo.Abp.AspNetCore.Mvc.ExceptionHandling return; } - Logger.LogException(context.Exception); - HandleAndWrapException(context); } @@ -65,20 +68,21 @@ namespace Volo.Abp.AspNetCore.Mvc.ExceptionHandling protected virtual void HandleAndWrapException(ExceptionContext context) { + //TODO: Trigger an AbpExceptionHandled event or something like that. + context.HttpContext.Response.Headers.Add(AbpHttpConsts.AbpErrorFormat, "true"); + context.HttpContext.Response.StatusCode = (int)_statusCodeFinder.GetStatusCode(context.HttpContext, context.Exception); - context.HttpContext.Response.StatusCode = - (int)_statusCodeFinder.GetStatusCode(context.HttpContext, context.Exception); + var remoteServiceErrorInfo = _errorInfoConverter.Convert(context.Exception); - context.Result = new ObjectResult( - new RemoteServiceErrorResponse( - _errorInfoConverter.Convert(context.Exception) - ) - ); + context.Result = new ObjectResult(new RemoteServiceErrorResponse(remoteServiceErrorInfo)); + context.Exception = null; //Handled! - //TODO: Trigger an AbpExceptionHandled event or something like that. + var logLevel = context.Exception.GetLogLevel(); - context.Exception = null; //Handled! + Logger.LogWithLevel(logLevel, $"---------- {nameof(RemoteServiceErrorInfo)} ----------"); + Logger.LogWithLevel(logLevel, _jsonSerializer.Serialize(remoteServiceErrorInfo, indented: true)); + Logger.LogException(context.Exception, logLevel); } } } diff --git a/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/DefaultHttpExceptionStatusCodeFinder.cs b/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/DefaultHttpExceptionStatusCodeFinder.cs index 445ecf3884..b8bb5be3dd 100644 --- a/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/DefaultHttpExceptionStatusCodeFinder.cs +++ b/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/DefaultHttpExceptionStatusCodeFinder.cs @@ -23,8 +23,6 @@ namespace Volo.Abp.AspNetCore.Mvc.ExceptionHandling public virtual HttpStatusCode GetStatusCode(HttpContext httpContext, Exception exception) { - //TODO: If the exception has error code than we can determine the exception from it! - if (exception is IHasErrorCode exceptionWithErrorCode && !exceptionWithErrorCode.Code.IsNullOrWhiteSpace()) { diff --git a/src/Volo.Abp.Core/Microsoft/Extensions/Logging/LoggerExtensions.cs b/src/Volo.Abp.Core/Microsoft/Extensions/Logging/LoggerExtensions.cs index e60e8ec6ca..1677e62090 100644 --- a/src/Volo.Abp.Core/Microsoft/Extensions/Logging/LoggerExtensions.cs +++ b/src/Volo.Abp.Core/Microsoft/Extensions/Logging/LoggerExtensions.cs @@ -58,13 +58,26 @@ namespace Microsoft.Extensions.Logging public static void LogException(this ILogger logger, Exception ex, LogLevel? level = null) { - logger.LogWithLevel( - level ?? (ex as IHasLogLevel)?.LogLevel ?? LogLevel.Error, - ex.Message, - ex - ); + var selectedLevel = level ?? ex.GetLogLevel(); + logger.LogWithLevel(selectedLevel, ex.Message, ex); LogDetails(logger, ex); + LogData(logger, ex, selectedLevel); + } + + private static void LogData(ILogger logger, Exception exception, LogLevel logLevel) + { + if (exception.Data == null || exception.Data.Count <= 0) + { + return; + } + + logger.LogWithLevel(logLevel, "---------- Exception Data ----------"); + + foreach (var key in exception.Data.Keys) + { + logger.LogWithLevel(logLevel, $"{key} = {exception.Data[key]}"); + } } private static void LogDetails(ILogger logger, Exception exception) diff --git a/src/Volo.Abp.Core/System/AbpExceptionExtensions.cs b/src/Volo.Abp.Core/System/AbpExceptionExtensions.cs index c3a5baaa96..d67f1b253f 100644 --- a/src/Volo.Abp.Core/System/AbpExceptionExtensions.cs +++ b/src/Volo.Abp.Core/System/AbpExceptionExtensions.cs @@ -1,4 +1,6 @@ using System.Runtime.ExceptionServices; +using Microsoft.Extensions.Logging; +using Volo.Abp.Logging; namespace System { @@ -16,5 +18,18 @@ namespace System { ExceptionDispatchInfo.Capture(exception).Throw(); } + + /// + /// Try to get a log level from the given + /// if it implements the interface. + /// Otherwise, returns the . + /// + /// + /// + /// + public static LogLevel GetLogLevel(this Exception exception, LogLevel defaultLevel = LogLevel.Error) + { + return (exception as IHasLogLevel)?.LogLevel ?? defaultLevel; + } } } \ No newline at end of file