Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Display custom error page and show exception details

I have a custom Errors controller that looks like this:

public class ErrorsController : BaseController
{
    public ActionResult RaiseError(string error = null)
    {
        string msg = error ?? "An error has been thrown (intentionally).";
        throw new Exception(msg);
    }

    public ActionResult Error404()
    {
        Response.TrySkipIisCustomErrors = true;
        Response.StatusCode = (int)HttpStatusCode.NotFound;
        return View();
    }

    public ActionResult Error500()
    {
        Response.TrySkipIisCustomErrors = true;

        var model = new Models.Errors.Error500()
        {
            ServerException = Server.GetLastError(),
            HTTPStatusCode = Response.StatusCode
        };

        return View(model);
    }
}

My Errors500.cshtml looks like this:

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Error500</title>
</head>
<body>
    <div>
        An internal error has occurred.
            @if (Model != null && Model.ServerException != null &&                 HttpContext.Current.IsDebuggingEnabled)
    {
        <div>
            <p>
                <b>Exception:</b> @Model.ServerException.Message<br />
            </p>
            <div style="overflow:scroll">
                <pre>
                    @Model.ServerException.StackTrace
                </pre>
            </div>
        </div>
    }
    </div>

</body>
</html>

and my web.config has my error handlers specified as such:

<system.webServer>
<httpErrors errorMode="Custom" existingResponse="Replace" >
  <remove statusCode="404" subStatusCode="-1" />
  <error statusCode="404" subStatusCode="-1" responseMode="ExecuteURL" path="/Errors/Error404" />
  <remove statusCode="500" subStatusCode="-1" />
  <error statusCode="500" subStatusCode="-1" responseMode="ExecuteURL" path="/Errors/Error500" />
</httpErrors>

The problem is: everytime I call /errors/raiseerror to test my 500 handling; I'm redirected to errors/error500 (fine). However, the exception data isn't rendered on the page because the Server.GetLastError() call returns null instead of the exception thrown by RaiseError().

What's the best way to handle a custom 500 error page where that custom page can render out the exception details as well?

like image 786
Frank Rosario Avatar asked Nov 01 '13 21:11

Frank Rosario


1 Answers

The easiest way to go about this is:

Use MVC's built-in support to handle Exceptions. By default MVC uses HandleErrorAttribute that is registered in App_Start\FilterConfig.cs:

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new HandleErrorAttribute());
}

Now make sure you have a view called Error in Views\Shared folder. The view by default has model of type HandleErrorInfo with a property named Exception. You can show the Exception message and other details if you want like this:

Error.cshtml

@model HandleErrorInfo

@if(Model != null)
{       
    @Model.Exception.Message
}

You can customize the Error.cshtml page the way you want...

like image 129
Leniel Maccaferri Avatar answered Sep 30 '22 15:09

Leniel Maccaferri