dotnet / dotnet/aspnetcore

ProblemDetailsContext for CustomizeProblemDetails never contains an Exception for Controllers

Open
#65,697 2 comments 0 reactions 0 assignees View on GitHub
area-mvc feature-problem-details
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 5h
Merged PRs (30d)
276

Description

### Is there an existing issue for this?

- [x] I have searched the existing issues

### Describe the bug

As the title states, when using `ProblemDetailsOptions.CustomizeProblemDetails` with Controllers, the `ProblemDetailsContext` will never contain an Exception when using ExceptionHandlerMiddleware. From what I can see, the issue stems from different implementations of `IProblemDetailsWriter`.

`DefaultProblemDetailsWriter` registered by `AddProblemDetails` passes the `ProblemDetailsContext` created by the ExceptionHandlerMiddleware, which contains the exception.

Image

However, 'AddControllers' registers `DefaultApiProblemDetailsWriter` which does not call `ProblemDetailsOptions.CustomizeProblemDetails` directly but through `ProblemDetailsFactory`. This creates its own context but without the exception (because its not directly available within `ProblemDetailsFactory`).

Image

There are many situations where an Exception may not be available but the availability should not be depending on whether you use Controller or Minimal API.

### Expected Behavior

An unhandled Exception is included in the `ProblemDetailsContext` passed to `ProblemDetailsOptions.CustomizeProblemDetails` when using Controllers.

### Steps To Reproduce

Program:
```csharp
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();
builder.Services.AddProblemDetails(options =>
{
options.CustomizeProblemDetails = context =>
{
if (context.Exception is not null)
{
// this will never be called
context.ProblemDetails.Detail = context.Exception.ToString();
}
};
});

var app = builder.Build();

app.UseExceptionHandler();
app.MapControllers();
app.Run();
```
Controller:
```csharp
[ApiController]
[Route("[controller]")]
public class FailController : ControllerBase
{
[HttpGet]
public ActionResult Get()
=> throw new Exception("BOOM!");
}
```

### Exceptions (if any)

_No response_

### .NET Version

10.0.103

### Anything else?

Workaround can be made by going through the `HttpContext`, but this behavior is confusing and I doubt this was intentional.

Logically, I don't think the `CustomizeProblemDetails` should be called within the factory, but within the `DefaultApiProblemDetailsWriter`, like it is with `DefaultProblemDetailsWriter`

Image
If `ProblemDetailsFactory` is purely intended for use within aspnet itself then moving the call to `CustomizeProblemDetails` should achieve the same result with the added option to retain the original context.

If you want to, I would love to try and make a PR on it :)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.