3

I'm currently working on an ASP.NET Core 2 MVC application. I try to figure out how global exception handling in Startup.cs works.

So far so good, I can use the regular app.UseStatusCodePages() middleware.

Nevertheless, when I try to use the app.UseStatusCodePagesWithReExecute to show the HTTP status code on my view, I only get a standard HTTP 500 page and there is no redirect to my CustomError action in my Error controller.

For demo purpose, I run my app in Production Environment, not in Development.

I throw my error in my ValuesController. The ValuesController looks like that:

public class ValuesController : Controller
{
    public async Task<IActionResult> Details(int id)
    {
        throw new Exception("Crazy Error occured!");
    }
}

My Startup.cs looks like that:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    // Global Exception Handling, I run in Production mode
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else // I come into this branch
    {
        //app.UseExceptionHandler("/Error/Error");

        // My problem starts here: I cannot redirect to my custom error method... 
        //there is only a standard http 500 screen
        app.UseStatusCodePagesWithReExecute("/Error/CustomError/{0}");
    }

    app.UseStaticFiles();

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Values}/{action=Index}/{id?}");
    });
}

Finally, my ErrorController looks like that:

public class ErrorController : Controller
{
    public IActionResult CustomError(string code)
    {
        // I only want to get here in debug, to get the code
        // unfortunately it never happens :/
        return Content("Error Test");
    }
}

Unfortunately, I cannot redirect to my CustomError method and get the HTTP status code according to the exception.

There is only a standard chrome HTTP 500 page, thus nothing works.

Set
  • 47,577
  • 22
  • 132
  • 150
TimHorton
  • 865
  • 3
  • 13
  • 33

1 Answers1

3

Status Code Pages Middleware doesn't work with unhandled exceptions during pipeline execution but checks the response status code (for responses without bodies).

If you modify action method to something like this, you will get the custom error page:

 public async Task<IActionResult> Details(int id)
 {
    return new StatusCodeResult(500);
 }

For exceptions handling look into UseExceptionHandler method. For example:

app.UseExceptionHandler("/Error/CustomError/500");

Note, you can use both UseExceptionHandler and UseStatusCodePagesWithReExecute in your app.

Set
  • 47,577
  • 22
  • 132
  • 150
  • Thank you, it works perfectly when I return the StatusCodeResult... Hm, but how can i catch Runtime exceptions without using a try catch in MVC? :) – TimHorton Apr 02 '18 at 18:38
  • 1
    @TimHorton if you want to catch exceptions in MVC middleware only, use [Exception Filter](https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/filters#exception-filters). If for all pipeline exception, then use another version of ExceptionHandler: `app.UseExceptionHandler(errorApp => { errorApp.Run(async context => ... ) }` (check [this SO post](https://stackoverflow.com/questions/38014379/error-handling-in-asp-net-core-1-0-web-api-sending-ex-message-to-the-client/38015155#38015155) for sample). And of course, you always may write your own middleware for global try-catch – Set Apr 02 '18 at 18:47