Generate problem details inside exception filter in ASP.NET Core 6 Web API
Asked Answered
T

1

6

The ControllerBase class has this very handy Problem method that automatically generates RFC7807 error responses. We just have to specify the title and the status code and the Problem method will fill in the rest (E.G. Type = URI reference [RFC3986]).

Now, I am designing a global exception filter that will return error responses based on the exception encountered. But I also want to generate errors in the RFC7807 format. By itself, the ProblemDetails type cannot generate values on its own. I would like to be able to just provide the Title and status code and not care about other values. I will not be able to use ControllerBase.Problem since errors might occur even before controllers are created.

Is there a way to automatically generate a ProblemDetails object inside and exception filter? I am using ASP.NET Core 6.0.

Thurlough answered 7/4, 2023 at 19:32 Comment(1)
You might be interested in the Problem Details Middleware developed by Kristian Hellang. You can read about it in this blog post by Andrew Lock.Farquhar
T
8

I figured it out.

The ControllerBase class has this:

_problemDetailsFactory = HttpContext?.RequestServices?.GetRequiredService<ProblemDetailsFactory>();

It seems that an implementation of ProblemDetailsFactory is being injected. So in my ExceptionFilter, I just do:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.Infrastructure;

public class ApiErrorsFilter : IExceptionFilter
{
    private ProblemDetailsFactory _problemDetailsFactory;

    public ApiErrorsFilter(ProblemDetailsFactory problemDetailsFactory) => _problemDetailsFactory = problemDetailsFactory;

    public void OnException(ExceptionContext context)
    {
        var exception = context.Exception;
        var httpContext = context.HttpContext;

        // sample response
        var problemDetails = _problemDetailsFactory.CreateProblemDetails(httpContext, statusCode: 500, title: "API error" );
        context.Result = new ObjectResult(problemDetails){
            StatusCode = problemDetails.Status
        };

        context.ExceptionHandled = true;
    }

}

This is good enough for me, but feel free to add more answers/comments if there is a better way.

Thurlough answered 8/4, 2023 at 12:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.