5.3 Error Handling


By default, ASP.NET displays generic error pages for any server errors that occur, such as missing files or internal server errors. The default display for a 404 error is shown in Figure 5-6.

Figure 5-6. Default ASP.NET Display for HTTP 404 File-Not-Found Error

graphics/05fig06.gif

If you prefer, you can build specific error pages to display to users when an error occurs in your application. You can specify a particular page to be displayed when an error occurs on a page-by-page basis by using the ErrorPage attribute of the Page directive with the URL of the error page, as shown in Listing 5-3. It is more likely, however, that you will want to specify a general error page, or a collection of specific error pages, to be used for an entire application. Application-wide error pages can be specified in your web.config file by using the customErrors element, as shown in Listing 5-4.

Listing 5-3 Specifying an Error Page
 <%@ Page ErrorPage="MyErrorPage.aspx" %> 
Listing 5-4 Specifying Error Pages for an Application
 <configuration>   <system.web>     <customErrors defaultredirect='ouch.aspx' mode='On'>       <error statuscode='404' redirect='nofile.aspx'/>     </customErrors>   </system.web> </configuration> 

With the customErrors element, you can specify a unique error page (or URL) for each HTTP error code, and one top-level page that users will be redirected to if none of the specific error codes are encountered . The other attribute of the customErrors element, mode , controls when these custom error pages are displayed. By default, mode is set to RemoteOnly , which shows the custom error pages only when the pages are accessed by a remote machine (any machine but the server). This is useful because the ASP.NET error page that is displayed for an unhandled exception contains useful information, including source code and a stack trace. If you are developing on a test server machine, it is useful to see the full diagnostic information in the generated error page for unhandled exceptions. However, you probably don't want clients to see that level of detail, which is exactly what the RemoteOnly setting does for you ”show the detailed error information when the page is accessed locally, and show whatever you have specified in the customErrors element when the page is accessed remotely. Table 5-4 shows the complete set of attributes associated with the customErrors element, with associated descriptions.

Table 5-4. customErrors Attributes

customErrors Attribute

Values

Description

Mode

  On  

Off

RemoteOnly

Specifying

  On  
forces display of custom errors locally as well as remotely.

Specifying Off does not use custom errors, but always shows the default ASP.NET error pages.

Specifying RemoteOnly (the default) shows the ASP.NET error pages locally, but the custom error pages remotely.

defaultRedirect

URL to redirect to

If there is no specific page designated to display when an error is encountered, the URL specified here is used.

5.3.1 Unhandled Exceptions

One of the most compelling aspects of working with the CLR is that even poorly written code is unlikely to cause your program to crash. Because all memory is accessed through references, array boundaries are maintained and checked on access, and direct pointers into memory are a thing of the past, [12] it is almost impossible to cause a program error by writing to the wrong block of memory. This is not to say, however, that programs are now guaranteed error-free, but that errors are recognized by the runtime and can be dealt with programmatically.

[12] Note that it is still possible to use pointers in C# with code that is marked as "unsafe," and managed C++ still works directly with pointers. Code written with pointers is known as unverifiable code and can be prevented from running at all by imposing the appropriate Code Access Security restriction. Most code written for ASP.NET applications will be verifiable C# or VB.NET code.

Whenever errors are detected by the runtime, such as a divide by zero or a failure to connect to a database, an exception is thrown. Ideally, your ASP.NET pages and components should trap any potential exceptions and decide what to do for recovery where the exception occurred. Often, however, programs do not check for all potential exceptions, so any unhandled exceptions propagate up the call stack to a top-level exception handler provided by ASP.NET. If you receive an unhandled exception when you are running on the server machine, ASP.NET will print a useful diagnostic message containing a stack trace and source code showing the location the error was generated. If your application is accessed remotely when an unhandled exception occurs, however, your clients will see an error page that looks like the one shown in Figure 5-7.

Figure 5-7. Default ASP.NET Display for Unhandled Exceptions

graphics/05fig07.gif

As a developer, you should be embarrassed if your clients ever see this page. Not only does it state that an unhandled error occurred on the server, but it gives advice on how to configure the application to avoid showing this page again. The second piece of advice given by this page is one you should always follow: Include a customErrors element in your configuration file that provides a redirection to your own internal error handling page so that clients never see this page. The only disadvantage to this solution is that you lose the exception information when ASP.NET redirects clients to the default error page you specify, so there is no way to log information about the error or to give clients information to pass along to you so that you can analyze what went wrong.

To deal with this lack of error information in your default redirection page, you can provide a handler for the Error event of the HttpApplication class. This event is issued whenever there is an unhandled exception, and it is called before the internal ASP.NET unhandled event code executes, giving you the chance to deal with the error yourself and perhaps not display an error page at all. To add a handler to this even, create a global.asax file, and define a function named Application_Error , as shown in Listing 5-5. By calling the ClearError() method of the HttpContext class, you can prevent ASP.NET's unhandled exception code from ever being executed. Be warned , however, that calling ClearError() also prevents any redirection to other error pages you may have defined for specific HTTP error codes.

Listing 5-5 Dealing with Unhandled Exceptions
 <!-- global.asax --> <%@ Application Language='VB' %> <script runat=server> Protected Sub Application_Error(src As Object, e As EventArgs)   Dim ex As Exception = Server.GetLastError()   ' do something with the error here, such as   ' writing to the event log   ' The following line writes the error message   ' to the event log with a source of "MyApp"   ' Note that the "MyApp" source must be preregistered   EventLog.WriteEntry("MyApp", ex.Message, _                       EventLogEntryType.Error)   ' At this point you could call:   ' Context.ClearError();   ' to clear the error and continue execution.   ' In general, you don't want to do this, because it will   ' prevent ASP.NET from redirecting to your error pages End Sub </script> 

The one other possible approach, which gives you the best of both worlds , is to look at the error in your Error handler, and if it is an unhandled exception, perform a Server.Transfer() to a custom error page you have built that displays information to users about the unhandled exception, which they could then relay to you. If it is any other type of error, just let it pass through, and ASP.NET will take care of redirecting users to the appropriate error page. It is important to perform the Server.Transfer() to the error page to retain the exception information, because performing a Server.Redirect() cause a round-trip back to the client, and the error information will be lost. Listing 5-6 shows the technique for performing the test on the exception and executing a transfer to the error page, and Listing 5-7 shows the sample error page that then has access to the exception information. Note that the exception typically is passed through the Inner Exception field of the Exception class.

Listing 5-6 Retaining Exception Information
 ' in global.asax Protected Sub Application_Error(sender As Object, _                                   e As EventArgs)   Dim ex As Exception = Server.GetLastError()   If ex.GetType() Is GetType(HttpUnhandledException) Then     Server.Transfer("MyErrorPage.aspx")   End If   ' Otherwise, we fall through, and the normal ASP.NET   ' error handling takes over End Sub 
Listing 5-7 Accessing Exception Information in an Error Page
 <!-- MyErrorPage.aspx --> <%@ Page Language='VB' %> <html> <h1>My error page</h1> <% Dim ex As Exception = Server.GetLastError()     If Not ex Is Nothing Then       Dim err As String = ""       If Not ex.InnerException Is Nothing Then            Response.Output.Write("The error was: {0}", _                         ex.InnerException.Message)   End If End If %> </html> 


Essential ASP.NET with Examples in Visual Basic .NET
Essential ASP.NET with Examples in Visual Basic .NET
ISBN: 0201760398
EAN: 2147483647
Year: 2003
Pages: 94
Authors: Fritz Onion

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net