proudmonkey / AutoWrapper

A simple, yet customizable global exception handler and Http response wrapper for ASP.NET Core APIs.
MIT License
677 stars 82 forks source link

can not catch the 500 errors. #25

Closed larssonsun closed 4 years ago

larssonsun commented 4 years ago

part of the .proj:

... `

**<PackageReference Include="autowrapper.core" Version="3.0.0" />**
<PackageReference Include="FluentValidation" Version="8.6.1" />
<PackageReference Include="FluentValidation.AspNetCore" Version="8.6.1" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0" />

**netcoreapp3.1** ` ... part of the startup.cs: ... public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseApiResponseAndExceptionWrapper(new AutoWrapperOptions { ShowStatusCode = true }); ... the stack: fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1] An unhandled exception has occurred while executing the request. System.FormatException: **Input string was not in a correct format**. at System.Number.ThrowOverflowOrFormatException(ParsingStatus status, TypeCode type) at System.Number.ParseInt32(ReadOnlySpan`1 value, NumberStyles styles, NumberFormatInfo info) at System.Convert.ToInt32(String value) at RESTfulAPISample.Api.Controller.ProductController.GetById(Guid id) in /Users/larsson/Documents/working/proj/_netcore/RESTfulAPISample/RESTfulAPISample.Api/Controllers/ProductController.cs:line 156 at lambda_method(Closure , Object ) at Microsoft.Extensions.Internal.ObjectMethodExecutorAwaitable.Awaiter.GetResult() at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync() --- End of stack trace from previous location where exception was thrown --- at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Logged|17_1(ResourceInvoker invoker) at Microsoft.AspNetCore.Routing.EndpointMiddleware.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 Marvin.Cache.Headers.HttpCacheHeadersMiddleware.HandleResponse(HttpContext httpContext) at Marvin.Cache.Headers.HttpCacheHeadersMiddleware.Invoke(HttpContext httpContext) at Microsoft.AspNetCore.ResponseCaching.ResponseCachingMiddleware.Invoke(HttpContext httpContext) at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext) at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider) at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context) fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[3] An exception was thrown attempting to display the error page. System.ObjectDisposedException: **Cannot access a closed Stream.** at System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count) at System.IO.MemoryStream.WriteAsync(ReadOnlyMemory`1 buffer, CancellationToken cancellationToken) --- End of stack trace from previous location where exception was thrown --- at System.IO.Pipelines.StreamPipeWriter.FlushAsyncInternal(CancellationToken cancellationToken) at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context) fail: AutoWrapper.AutoWrapperMiddleware[0] [500]: Unhandled Exception occurred. Unable to process the request. System.FormatException: **Input string was not in a correct format**. at System.Number.ThrowOverflowOrFormatException(ParsingStatus status, TypeCode type) at System.Number.ParseInt32(ReadOnlySpan`1 value, NumberStyles styles, NumberFormatInfo info) at System.Convert.ToInt32(String value) at RESTfulAPISample.Api.Controller.ProductController.GetById(Guid id) in /Users/larsson/Documents/working/proj/_netcore/RESTfulAPISample/RESTfulAPISample.Api/Controllers/ProductController.cs:line 156 at lambda_method(Closure , Object ) at Microsoft.Extensions.Internal.ObjectMethodExecutorAwaitable.Awaiter.GetResult() at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync() --- End of stack trace from previous location where exception was thrown --- at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Logged|17_1(ResourceInvoker invoker) at Microsoft.AspNetCore.Routing.EndpointMiddleware.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 Marvin.Cache.Headers.HttpCacheHeadersMiddleware.HandleResponse(HttpContext httpContext) at Marvin.Cache.Headers.HttpCacheHeadersMiddleware.Invoke(HttpContext httpContext) at Microsoft.AspNetCore.ResponseCaching.ResponseCachingMiddleware.Invoke(HttpContext httpContext) at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext) at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider) at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context) at AutoWrapper.Base.WrapperBase.InvokeAsyncBase(HttpContext context, AutoWrapperMembers awm) info: AutoWrapper.AutoWrapperMiddleware[0] Source:[::1] Request: GET http localhost:5000/product/5a30526a-a574-4fa9-ab5a-1b30e553b9bd Responded with [500] in 45ms fail: Microsoft.AspNetCore.Server.Kestrel[13] Connection id "0HLTA3078EHRE", Request id "0HLTA3078EHRE:00000006": An unhandled exception was thrown by the application. System.ObjectDisposedException: **Cannot access a closed Stream**. at System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count) at System.IO.MemoryStream.WriteAsync(ReadOnlyMemory`1 buffer, CancellationToken cancellationToken) --- End of stack trace from previous location where exception was thrown --- at System.IO.Pipelines.StreamPipeWriter.FlushAsyncInternal(CancellationToken cancellationToken) at AutoWrapper.Base.WrapperBase.InvokeAsyncBase(HttpContext context, AutoWrapperMembers awm) at AutoWrapper.AutoWrapperMiddleware.InvokeAsync(HttpContext context) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application) fail: Microsoft.AspNetCore.Server.Kestrel[13] Connection id "0HLTA3078EHRE", Request id "0HLTA3078EHRE:00000006": An unhandled exception was thrown by the application. System.ObjectDisposedException: **Cannot access a closed Stream**. at System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count) at System.IO.MemoryStream.WriteAsync(ReadOnlyMemory`1 buffer, CancellationToken cancellationToken) --- End of stack trace from previous location where exception was thrown --- at System.IO.Pipelines.StreamPipeWriter.FlushAsyncInternal(CancellationToken cancellationToken) at System.IO.Pipelines.StreamPipeWriter.CompleteAsync(Exception exception) at Microsoft.AspNetCore.Http.StreamResponseBodyFeature.CompleteAsync() at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.FireOnCompletedAwaited(Task currentTask, Stack`1 onCompleted) info: Microsoft.AspNetCore.Hosting.Diagnostics[2] Request finished in 49.628ms 500
proudmonkey commented 4 years ago

@larssonsun would you be able to provide a scenario to replicate this? I'm not sure I'm following. Thank you.

larssonsun commented 4 years ago

I'm afraid I should apologize for my issue.

i use autowrapper and Marvin.Cache.Headers at the same proj,

If middleware is used in the following order it will cause autowrapper to throw an exception that cannot be caught:

part of startup.cs:

` ...

        app.UseApiResponseAndExceptionWrapper(new AutoWrapperOptions { ShowStatusCode = true });
        app.UseResponseCaching();
        app.UseHttpCacheHeaders();
        app.UseRouting();

        ...

`

it will throw the exception:

Cannot access a closed Stream.

Middleware must be used in the following order:

` app.UseResponseCaching(); app.UseHttpCacheHeaders(); app.UseApiResponseAndExceptionWrapper(new AutoWrapperOptions { ShowStatusCode = true }); app.UseRouting();

`

and after this every thing is fine.

thank you for your reply.

proudmonkey commented 4 years ago

@larssonsun Thank you for confirming that. :)

I'll looking into the exception message to JSON thing. I'll keep you posted.

By the way, Have you tried passing a ValidationError object to display Model errors instead of passing it as a string as a message in ApiException object?

ApiException(IEnumerable<ValidationError> errors, int statusCode = 400)
proudmonkey commented 4 years ago

@larssonsun - One more thing. would you be able to open a new issue for the Exception message not recognizing JSON so I can close this thread to avoid mixing things up? Thanks!