Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UseExceptionHandler vs UseStatusCodePagesWithRedirects

I've been reading about errors handling in ASP.NET Core and I came across these 2 ways:

  • UseExceptionHandler("/error")
  • UseStatusCodePagesWithRedirects("/error/{0}");

I'm wondering what's the difference between the two? Both redirect to an error page so why use one over the other? I even saw some people using them both at the same time.

like image 631
Haytam Avatar asked Jun 30 '18 21:06

Haytam


People also ask

What is UseExceptionHandler?

UseExceptionHandler(IApplicationBuilder, Action<IApplicationBuilder>) Adds a middleware to the pipeline that will catch exceptions, log them, and re-execute the request in an alternate pipeline. The request will not be re-executed if the response has already started. UseExceptionHandler(IApplicationBuilder, String)

What is UseDeveloperExceptionPage?

UseDeveloperExceptionPage(IApplicationBuilder) Captures synchronous and asynchronous Exception instances from the pipeline and generates HTML error responses.

How does NET Core handle global exception?

Use the UseExceptionHandler middleware in ASP.NET Core So, to implement the global exception handler, we can use the benefits of the ASP.NET Core build-in Middleware. A middleware is indicated as a software component inserted into the request processing pipeline which handles the requests and responses.


1 Answers

You are right that both middlewares do provide error pages. However, they have two different use cases which will make it useful to actually use both at the same time in an application. To understand the differences, let’s take a look at how the middlewares actually work internally.

This is essentially what the StatusCodePages middleware does:

// …
await _next(context);
// …

// Do nothing if a response body has already been provided.
if (context.Response.HasStarted
    || context.Response.StatusCode < 400
    || context.Response.StatusCode >= 600
    || context.Response.ContentLength.HasValue
    || !string.IsNullOrEmpty(context.Response.ContentType))
{
    return;
}

var statusCodeContext = new StatusCodeContext(context, _options, _next);
await _options.HandleAsync(statusCodeContext);

It executes the pipeline by calling _next and after the call has returned (meaning that all following middlewares have executed), it will inspect the current response: Basically, if there’s an error status code or no content at all, it will execute the status code page, signalizing the HTTP status code.

The ExceptionHandler middleware on the other hand does something very different:

try
{
    await _next(context);
}
catch (Exception ex)
{
    // …
    try
    {
        // …

        await _options.ExceptionHandler(context);

        // …
        return;
    }
    catch (Exception ex2)
    {
        // Suppress secondary exceptions, re-throw the original.
        _logger.ErrorHandlerException(ex2);
    }
    throw; // Re-throw the original if we couldn't handle it
}

This will try to invoke the middleware pipeline and catch any exception it might produce. Then, it will attempt to run the registered exception handler (which, when setting a path basically means to invoke that path internally and return its response).

So to sum this up:

  • The StatusCodePages middleware will handle non-successful status code responses and allows you to specify e.g. custom error pages for things like a 404 Not Found.
  • The ExceptionHandler middleware on the other hand will catch unhandled exceptions in your application and allows you to handle those gracefully for the end user.

Both middlewares have different purposes and actually don’t overlap in what they do. So it often makes sense to include both of them, unless you handle these issues differently of course; e.g. an API will probably not need status code pages, but might still want an exception handler that returns a generic failure and logs everything properly.

like image 81
poke Avatar answered Oct 11 '22 02:10

poke