Programming Microsoft ASP.NET 4 - Dino Esposito [146]
At this point, ASP.NET users are shown a standard error page that some developers familiarly call the YSOD (yellow screen of death), which is a spinoff of the just as illustrious BSOD (blue screen of death) that we all have come to know after years of experience with the Microsoft Windows operating system. An unhandled exception originates an error and stops the application.
As a developer, how should you deal with unhandled exceptions in ASP.NET applications?
Default Error Pages
When an unrecoverable error occurs in an ASP.NET page, users always receive a page that, more or less nicely, informs them that something went wrong at a certain point. ASP.NET catches any unhandled exception and transforms it into a page for the user, as shown in Figure 7-1.
Figure 7-1. The error page generated by an unhandled exception (for the local user).
As you can guess from looking at the screen shot, the sample page contains a button whose click handler is bound to the following code:
protected void Button1_Click(Object sender, EventArgs e)
{
throw new NotImplementedException();
}
More than the code itself, which is fairly trivial, the most interesting part of the story is how ASP.NET handles the exception and the machinery that ultimately produces the markup of Figure 7-1.
First and foremost, the typical error page differs for local and remote users.
By default, local users—namely, any user accessing the application through the local host—receive the page shown in Figure 7-1. The page includes the call stack—the chain of method calls leading up to the exception—and a brief description of the error. Additional source code information is added if the page runs in debug mode. For security reasons, remote users receive a less detailed page, like the one shown in Figure 7-2.
Figure 7-2. The page does not provide information about the error.
ASP.NET provides a couple of global interception points for you to handle errors programmatically, at either the page level or the application level. The Page base class exposes an Error event, which you can override in your pages to catch any unhandled exceptions raised during the execution of the page. Likewise, an Error event exists on the HttpApplication class, too, to catch any unhandled exception thrown within the application.
Page-Level Error Handling
To catch any unhandled exceptions wandering around a particular page, you define a handler for the Error event. Here’s an example:
protected void Page_Error(Object sender, EventArgs e)
{
// Capture the error
var exception = Server.GetLastError();
// Resolve the error page based on the exception that occurred
// and redirect to the appropriate page
if (exception is NotImplementedException)
Server.Transfer("/ErrorPages/NotImplErrorPage.aspx");
else
Server.Transfer("/ErrorPages/GenericErrorPage.aspx");
// Clear the error
Server.ClearError();
}
You know about the raised exception through the GetLastError method of the Server object. In the Error handler, you can transfer control to a particular page and show a personalized and exception-specific message to the user. The control is transferred to the error page, and the URL in the address bar of the browser doesn’t change. If you use Server.Transfer to pass control, the exception information is maintained and the error page itself can call into GetLastError and display more detailed information. Finally, after the exception is fully handled, you clear the error by calling ClearError.
Using Server.Transfer instead of Response.Redirect is also relevant from a Search-Engine Optimization (SEO) perspective because it performs a server-side redirect that is “invisible” to client applications, including Web browsers and, more importantly, Web spiders.
Important
When displaying error messages, pay attention not to hand out sensitive