ASP .NET Core 3.1 中的"Unhandled"例外



我的日志文件中出现了一个异常。问题是我在Startup.Configure((方法中有一个全局异常处理程序:

app.UseExceptionHandler("/Home/Error");

它被实际调用了。因此,异常得到了处理。如何禁止将此消息放入日志文件?

谢谢!

ERROR|Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware|An unhandled exception has occurred while executing the request. Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException: Request body too large.
at Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException.Throw(RequestRejectionReason reason)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Http1ContentLengthMessageBody.OnReadStarting()
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.MessageBody.TryStart()
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Http1ContentLengthMessageBody.ReadAsyncInternal(CancellationToken cancellationToken)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpRequestStream.ReadAsyncInternal(Memory`1 buffer, CancellationToken cancellationToken)
at Microsoft.AspNetCore.WebUtilities.BufferedReadStream.EnsureBufferedAsync(Int32 minCount, CancellationToken cancellationToken)
at Microsoft.AspNetCore.WebUtilities.MultipartReaderStream.ReadAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken)
at Microsoft.AspNetCore.WebUtilities.StreamHelperExtensions.DrainAsync(Stream stream, ArrayPool`1 bytePool, Nullable`1 limit, CancellationToken cancellationToken)
at Microsoft.AspNetCore.WebUtilities.MultipartReader.ReadNextSectionAsync(CancellationToken cancellationToken)
at Microsoft.AspNetCore.Http.Features.FormFeature.InnerReadFormAsync(CancellationToken cancellationToken)
at Microsoft.AspNetCore.Mvc.ModelBinding.FormValueProviderFactory.AddValueProviderAsync(ValueProviderFactoryContext context)
at Microsoft.AspNetCore.Mvc.ModelBinding.CompositeValueProvider.CreateAsync(ActionContext actionContext, IList`1 factories)
at Microsoft.AspNetCore.Mvc.ModelBinding.CompositeValueProvider.TryCreateAsync(ActionContext actionContext, IList`1 factories)
at Microsoft.AspNetCore.Mvc.Controllers.ControllerBinderDelegateProvider.<>c__DisplayClass0_0.<<CreateBinderDelegate>g__Bind|0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>g__Awaited|6_0(ExceptionHandlerMiddleware middleware, HttpContext context, Task task)```

可靠地记录异常是全局异常处理程序实际上可以做的一件事。之后,它应该始终让异常继续。对于日志记录,它必须捕获范围很广,这意味着它会捕获致命异常,而这些异常应该始终被释放。全局处理程序是一种延迟修复任何问题的方法。甚至可能已经太晚了,无法正确记录任何内容,因为到那时大多数内容都已经超出了范围。

要知道如何正确处理它,我们首先需要对它进行分类。我使用这个分类系统:https://blogs.msdn.microsoft.com/ericlippert/2008/09/10/vexing-exceptions/

BadHttpRequestException看起来像一个Bonehead异常。那些你永远不应该忽视的,最好永远不要抓住。您应该修复的

然而,当我们处理网络时,有可能是外生或Vexing异常。如果它是其中之一,你应该尽可能靠近它被扔的地方,尽可能精确地接住它。还要向调用代码提供一些错误提示,因此不存在预期的结果。我曾经为一个复制的TryParse:写过这个例子

//Parse throws ArgumentNull, Format and Overflow Exceptions.
//And they only have Exception as base class in common, but identical handling code (output = 0 and return false).
bool TryParse(string input, out int output){
try{
output = int.Parse(input);
}
catch (Exception ex){
if(ex is ArgumentNullException ||
ex is FormatException ||
ex is OverflowException){
//these are the exceptions I am looking for. I will do my thing.
output = 0;
return false;
}
else{
//Not the exceptions I expect. Best to just let them go on their way.
throw;
}
}
//I am pretty sure the Exception replaces the return value in exception case. 
//So this one will only be returned without any Exceptions, expected or unexpected
return true;
}

Parse的Vexing部分?这些人就在那里被抓住,并通过bool返回进行交流。我必须捕获大量或重复处理代码,所以我尽最大努力进行is检查,以便稍后进行筛选。

对于一般体面的实践,我确实有一篇文章。连同上面的分类,它是我所有异常处理决策的核心。

我建议您不要禁用日志记录错误,因为这是发现用户问题的主要方法之一。无论如何,如果你确实想禁用错误日志记录,你可以从配置中进行。默认配置文件为"appsettings.json"文件:

"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": 6,
"Microsoft.Hosting.Lifetime": 6
}
}

这将抑制来自Microsoft或Hosting的任何错误消息。请注意,还有一个在开发环境中使用的"appsettings.Development.json"文件,您可能也希望在那里禁用日志。

最新更新