Matthias
Matthias

Reputation: 1436

ErrorController not invoked

I tried to customize the default behavior in order that I can change what gets returned in case of an exception inside my API controller.

I applied what I read inside the docs: https://learn.microsoft.com/en-us/aspnet/core/web-api/handle-errors?view=aspnetcore-5.0

Startup.cs:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseSwagger();
        app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "todo_list_app v1"));
    }
    else
    {
        app.UseExceptionHandler("/error");
    }
    [...]
}

ErrorController.cs:

[ApiController]
public class ErrorController : ControllerBase
{
    [Route("/error-local-development")]
    public IActionResult ErrorLocalDevelopment(
            [FromServices] IWebHostEnvironment webHostEnvironment)
    {
        if (webHostEnvironment.EnvironmentName != "Development")
        {
            throw new InvalidOperationException(
                    "This shouldn't be invoked in non-development environments.");
        }

        var context = HttpContext.Features.Get<IExceptionHandlerFeature>();

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

    [Route("/error")]
    public IActionResult Error() => Problem();
}

Upvotes: 0

Views: 736

Answers (2)

845614720
845614720

Reputation: 838

Your app.UseExceptionHandler("/error"); implies that unhandled exceptions will be caught by your ErrorController. You don't need the / in your [Route("/error")] it should just be [Route("error")].

I would recommend that you implement a body here to actually catch your exceptions and do whatever it is you want with them. Take a look at a very basic example that I wrote:

[Route("error")]
public ErrorResponseModel Error()
{
    var context = HttpContext.Features.Get<IExceptionHandlerFeature>();
    var exception = context.Error;

    Response.StatusCode = (int)HttpStatusCode.InternalServerError;

    return new ErrorResponseModel(exception);
}

This will catch your exception and then attach a 500 error to it. I user a custom model here, but you could return anything you wanted. You can also extend this functionality a bit more and check your type of exception and return different error codes depending on your exception type.

Upvotes: 1

Matthias
Matthias

Reputation: 1436

For what I wanted to achieve I had to call the UseExceptionHandler in development mode as well.

//app.UseDeveloperExceptionPage();
app.UseExceptionHandler("/error-local-development");

However, in the release mode, I did not expect that

 public IActionResult Error() => Problem();

would return nothing but an HTTP code. Which is no different than when having no route at all.

Upvotes: 0

Related Questions