Skip to content

Latest commit

 

History

History
113 lines (86 loc) · 3.34 KB

README.md

File metadata and controls

113 lines (86 loc) · 3.34 KB

Exception Handling

We use ExceptionHandlers to manage exceptions in one place, which we derive from IExceptionHandler.

public class CustomExceptionHandler : IExceptionHandler
{
    public ValueTask<bool> TryHandleAsync(HttpContext httpContext, Exception exception, CancellationToken cancellationToken)
    {
        ...

        return true;
    }
}

To use it, we register it with AddExceptionHandler

builder.Services.AddExceptionHandler<CustomExceptionHandler>();

⚠️

When registering multiple exception handlers you should pay attention to the order. It works according to the order of insertion.

Also need to call UseExceptionHandler to add the ExceptionHandlerMiddleware to the request pipeline

app.UseExceptionHandler();

We also use UseExceptionHandler in development mode because we expect a json object as a response because we use Postman.

We expect a json object but we don't want a json object in a different format for each exception, so we use the RFC standard Problem Detail object to standardize it.

To apply this standard in the exceptions we handle, we create the ProblemDetail object and give it to the response as follows

public async ValueTask<bool> TryHandleAsync(HttpContext httpContext, Exception exception,CancellationToken cancellationToken)
{
    var problemDetails = new ProblemDetails
    {
        ...
    };

    httpContext.Response.StatusCode = problemDetails.Status.Value;

    await httpContext.Response
        .WriteAsJsonAsync(problemDetails, cancellationToken);

    return true;
}

We fill the content of the object as below.

  • Type: Exception document link
  • Title: Exception name without the suffix 'exception' in standard case
  • Status: Status codes
  • Detail: Exception's message,
  • Extensions: Exception's extra fields, if any

Below you can see the example response body on the page

{
  "type": "http://localhost:5032/errors/parameter-required",
  "title": "Parameter Required",
  "status": 500,
  "detail": "param2 is required.",
  "name": "param2"
}

In order to have the same standard in the exceptions we do not handle, we have applied the same standard in all exceptions by using AddProblemDetails as below.

builder.Services.AddProblemDetails();

The only problem now is that exceptions like 404 don't have pages. For such exceptions, we use UseStatusCodePages. In this way, for example, instead of the browser's warning such as the page could not be found when you go to a path that does not exist, it shows our page and we display the exception with the ProblemDetail object.

The addition is as follows

app.UseStatusCodePages();

Resources