dotnet / AspNetCore.Docs

Documentation for ASP.NET Core
https://docs.microsoft.com/aspnet/core
Creative Commons Attribution 4.0 International
12.57k stars 25.31k forks source link

Handling exceptions using exception handler is not useful #24437

Closed Neutrino-Sunset closed 1 year ago

Neutrino-Sunset commented 2 years ago

The example of how to handle exceptions using an exception handler is not useful, or at least the explanation is incomplete.

The example demonstrates how to install an exception handler action using the route

[Route("/error-local-development")]

Containing

    return Problem(
        detail: context.Error.StackTrace,
        title: context.Error.Message);

The main problem with this approach is that although the Problem method permits you to set the statusCode, any attempt to do so will break the correct operation of the endpoint and result in the browser reporting an ERR_INCOMPLETE_CHUNKED_ENCODING error.

I suspect this is because the original action that generated the error has already started to write the result, so in the error handler action only the payload body can be set.

The later example in which an HttpResponseExceptionFilter filter is created does permit setting the StatusCode, but the example provided doesn't create an RFC 7807 compliant payload.

If you want to catch an exception, set the status code based on the exception, and return an RFC 7807 payload, then something like this seems to work and might be a more useful example.

 public class HttpResponseExceptionFilter : IActionFilter, IOrderedFilter
 {
    public int Order { get; } = int.MaxValue - 10;

    private readonly IWebHostEnvironment _env;

    public HttpResponseExceptionFilter(IWebHostEnvironment env)
    {
       _env = env;
    }

    public void OnActionExecuting(ActionExecutingContext context) { }

    public void OnActionExecuted(ActionExecutedContext context)
    {
       Exception exception = context.Exception;

       if (exception != null)
       {
          context.Result = ((ControllerBase)context.Controller).Problem(
             statusCode: (exception is HttpResponseException httpException) ? httpException.Status : 500,
             title: exception.Message,
             detail: _env.EnvironmentName == "Development" ? exception.ToString() : null
          );
          context.ExceptionHandled = true;
       }
    }
 }

Document Details

Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

Rick-Anderson commented 1 year ago

See https://learn.microsoft.com/en-us/aspnet/core/web-api/handle-errors?view=aspnetcore-7.0#problem-details-service