Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unhandled expections in are not being routed to my custom error page

My understanding is that if you added app.UseExceptionHandler(); and give it a path that ASP.Net is supposed to load that page when ever there is an error that is not caught in code but in my case I am still getting the normal "Http 500 Internal Server Error" page. I can take the path I give UseExceptionHandler() and put it right in my browser and it load the page fine so I know the path and the page work. Am I miss understanding how this is to work, is it broken, or am I doing something wrong?

Startup.cs:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    //if (env.IsDevelopment())
    //{
    //    app.UseDeveloperExceptionPage();
    //}

    app.UseExceptionHandler("/Error/ServerError");
    app.UseIISPlatformHandler();
    app.UseSession();
    app.UseStaticFiles();
    app.UseStatusCodePagesWithReExecute("/Error/PageNotFound");
    app.UseMvc();
}

Error Page Code:

//Get: "/Error/ServerError"
[Route("Error/ServerError")]
public IActionResult ServerError()
{
    return View(); //View is inside the Shared folder.
}

Error Page View:

<p>
    @ViewData["ErrorMessage"]
</p>

Please note that "Page not Found" errors are routed to the /Error/PageNotFound with no problems, it is just other errors are not.

EDIT: As a test I copied the string from UseStatusCodePagesWithReExecute into UseExceptionHandler but still get the generic 500 error page.

Edit 2: I should note that I am testing this error in two ways. The first is by simply having an action throw new DivideByZeroException(); and the other is to have a LINQ to Entities call into a Database that has been taken offline (and as such throwing a SqlException). Both ways just return the default HTTP 500 Internal Server Error and not my custom error.

like image 973
Matthew Verstraete Avatar asked Feb 05 '16 19:02

Matthew Verstraete


1 Answers

I originally thought the ordering of the UseXXX functions was important, but my testing proved that incorrect.

The only way I was able to get your example working was to modify the Error Page Code to the following:

[Route("Error/ServerError")]
public IActionResult ServerError()
{
    return View("Error/ServerError");
}

This assumes the following exists: [ProjectDir]\Views\Shared\Error\ServerError.cshtml

If you set the view name to simply "ServerError" and have your view located at [ProjectDir]\Views\Shared\ServerError.cshtml, there appears to be a bug in either the Microsoft.AspNet.Diagnostics or the Microsoft.AspNet.Mvc package.

When an erroneous request is made, the following will be written to the log:

info: Microsoft.AspNet.Mvc.Controllers.ControllerActionInvoker[1]
      Executing action method WebApplication2.Controllers.ErrorsController.Get with arguments () - ModelState is Valid'
fail: Microsoft.AspNet.Mvc.ViewFeatures.ViewResultExecutor[0]
       The view 'ServerError' was not found. Searched locations: /Views/Errors/ServerError.cshtml, /Views/Shared/ServerError.cshtml
fail: Microsoft.AspNet.Diagnostics.ExceptionHandlerMiddleware[0]
      An exception was thrown attempting to execute the error handler.
      System.InvalidOperationException: The view 'ServerError' was not found. The following locations were searched:
      /Views/Errors/ServerError.cshtml
      /Views/Shared/ServerError.cshtml.

The log clearly states an attempt was made to locate the view at /Views/Shared/ServerError.cshtml. Yet the request fails and uses the default error handler.

This issue has been logged on the aspnet/Diagnostics github repository here.

like image 113
Cobster Avatar answered Jan 02 '23 12:01

Cobster