Skip to content

AddExceptionHandler/UseExceptionHandler Fails in a non-Obvious Way #51888

Open
@shawnwildermuth

Description

@shawnwildermuth

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

With the new AddExceptionHandler and IExceptionHandler APIs, engaging the exception handler with UseExceptionHandler is confusing. For example, this code fails;

using ExHandler;
using Microsoft.AspNetCore.Diagnostics;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddExceptionHandler<GlobalExceptionHandler>();

var app = builder.Build();

app.UseExceptionHandler();       // Doesn't work

app.MapGet("/", () => {
  throw new Exception("Bad things happen to good developers");
});

app.Run();

public class GlobalExceptionHandler : IExceptionHandler
{
  public async ValueTask<bool> TryHandleAsync(HttpContext httpContext,
    Exception exception,
    CancellationToken cancellationToken)
  {
    httpContext.Response.ContentType = "text/plain";
    httpContext.Response.StatusCode = 501;
    await httpContext.Response.WriteAsync($"It don't work: {exception.Message}");
    return true;
  }
}

To make this work, you must pass in an empty lambda to the `UseExceptionHandler':

app.UseExceptionHandler(o => { }); // Works

Expected Behavior

Expected the empty call to UseExceptionHandler to work. Could not find documentation that explained this. ,

Steps To Reproduce

Example is at: https://github.com/shawnwildermuth/ExceptionHandlerRepro

Exceptions (if any)

I get an arcane message:

System.InvalidOperationException
  HResult=0x80131509
  Message=An error occurred when configuring the exception handler middleware. Either the 'ExceptionHandlingPath' or the 'ExceptionHandler' property must be set in 'UseExceptionHandler()'. Alternatively, set one of the aforementioned properties in 'Startup.ConfigureServices' as follows: 'services.AddExceptionHandler(options => { ... });' or configure to generate a 'ProblemDetails' response in 'service.AddProblemDetails()'.
  Source=Microsoft.AspNetCore.Diagnostics
  StackTrace:
   at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddlewareImpl..ctor(RequestDelegate next, ILoggerFactory loggerFactory, IOptions`1 options, DiagnosticListener diagnosticListener, IEnumerable`1 exceptionHandlers, IMeterFactory meterFactory, IProblemDetailsService problemDetailsService)
   at Microsoft.AspNetCore.Builder.ExceptionHandlerExtensions.<>c__DisplayClass5_0.<SetExceptionHandlerMiddleware>b__0(RequestDelegate next)
   at Microsoft.AspNetCore.Builder.ApplicationBuilder.Build()
   at Microsoft.AspNetCore.Builder.ApplicationBuilder.Build()
   at Microsoft.AspNetCore.Hosting.GenericWebHostService.<StartAsync>d__40.MoveNext()
   at Microsoft.Extensions.Hosting.Internal.Host.<<StartAsync>b__15_1>d.MoveNext()
   at Microsoft.Extensions.Hosting.Internal.Host.<ForeachService>d__18`1.MoveNext()
   at Microsoft.Extensions.Hosting.Internal.Host.<StartAsync>d__15.MoveNext()
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.<RunAsync>d__4.MoveNext()
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.<RunAsync>d__4.MoveNext()
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.Run(IHost host)
   at Program.<Main>$(String[] args) in C:\projects\codingshorts\net8exhandler\test\ExHandler\Program.cs:line 17

.NET Version

8.0.100-rc.2.23502.2

Anything else?

Note the failure is uncommented out, and the one that works is commented out. If this is expected behavior, we need it to be well documented since it is unobvious behavior.

Metadata

Metadata

Assignees

Labels

area-middlewareIncludes: URL rewrite, redirect, response cache/compression, session, and other general middlewares

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions