views:

75

answers:

2

I want to display the YSOD when it would be providing useful information during development or locally on the servers but a semi-generic page in other cases. I know that I could set the defaultRedirect attribute of the application's <customErrors> configuration tag in web.config, but I would rather do some processing to generate a page with slightly better information.

All of my controllers inherit from one central BaseController class where I have overridden OnException (essentially like this):

protected override void OnException(ExceptionContext filterContext) {
    //if something really bad happened and we get inside this if, 
    //just let the YSOD appear because there isn't anything we can do
    if (filterContext == null)
        return; 

    LogException(filterContext.Exception);

    //insert answer for question here:
    if (FigureOutIfDetailedYsodWouldBeDisplayed(filterContext)) 
        return;

    //what to actually do for end users
    filterContext.ExceptionHandled = true;
    filterContext.Result = View("ErrorPage", GetErrorModel(filterContext));
}

How should I implement FigureOutIfDetailedYsodWouldBeDisplayed (answer need not be code, a pointer in the right direction would be just fine)? My current implementation checks the raw url for the existence of "//localhost", but this solution feels clumsy and doesn't work all the time (for example if the dev has a host entry to type something other than localhost: a requirement our app used to have).

A: 

If you actually build using the Debug setting for Dev environments, and Release for production environments, you could always just do

#if DEBUG
    //Show YSOD
#else
    //Show friendly error page
#endif
TJMonk15
I'd say this is about as good as the current solution. We do build this way but occasionally could use the YSOD still on our servers to tell us setup things like bad folder permissions (would save a step in these cases by not requiring the person to look up the issue in the log). In this respect, the current production solution (which I am enhancing here with a more dynamic page) of using the `defaultRedirect` attribute is better (but worse for when we get an issue from the user).
Bill Barry
+2  A: 

Did you know you can also add custom error pages per HTTP Error code? Do you really need this custom error handling code then?

  <customErrors mode="RemoteOnly" defaultRedirect="Error/Default">
    <error statusCode="401" redirect="Error/AccessDenied" />
    <error statusCode="404" redirect="Error/NotFound" />
  </customErrors>

Also, unless you have really specific needs, I would recommend not writing this exception logging code yourself. Do yourself a favor and check out ELMAH. Seriously. [disclaimer: I am not involved in this project, just a very happy user]

All it takes is (litterally!) a few lines in your web.config, dropping a dll in your bin folder, and (if you want to log to a DB) a single .sql script.

From the project page:

"ELMAH (Error Logging Modules and Handlers) is an application-wide error logging facility that is completely pluggable. It can be dynamically added to a running ASP.NET web application, or even all ASP.NET web applications on a machine, without any need for re-compilation or re-deployment.

Once ELMAH has been dropped into a running web application and configured appropriately, you get the following facilities without changing a single line of your code:

  • Logging of nearly all unhandled exceptions.
  • A web page to remotely view the entire log of recoded exceptions.
  • A web page to remotely view the full details of any one logged exception.
  • In many cases, you can review the original yellow screen of death that ASP.NET generated - for a given exception, even with customErrors mode turned off.
  • An e-mail notification of each error at the time it occurs."
jeroenh
We currently have the equivalent of `<customErrors mode="RemoteOnly" defaultRedirect="error.htm" />` which works and suits all of our needs at the moment (outside of wanting slightly less generic messages for a few classes of issues). ELMAH is planned for, but would require significant more effort than this (due to various application architecture choices made long ago that I do not want to get into here, we unfortunately do not have just one or two web.configs to edit here; at last count I think there would have been 170 places to change for ELMAH). Regardless I cannot change web.config now.
Bill Barry
Note: 170+ different files would need to be changed for minimal ELMAH support across our system. That would get us the ability to log most unhandled exceptions (the vast majority of which are either build issues or server config issues) and tend to be only one time things (and we are talking maybe 1% of all exceptions here). Ideally ELMAH would be getting log notes for the handled exceptions too but this is an even bigger change - several weeks of development which wouldn't be sponsored by the clients (meaning it will take us months to get it done in bits around work that is payed for).
Bill Barry