Exploring Strategies for Exception Management


A well-designed exception management strategy for an application provides valuable information to assist technical support and the development team with the information they need to identify and resolve issues in the production environment. The exception management strategy should do the following:

  • Detect exceptions.

  • Log information regarding the exception.

  • Notify the appropriate agent.

Exceptions are caused by a breach of an implicit assumption made within code. Exceptions can be raised by a fault in an application's code, from code in a library outside of the application, or even from the common language runtime. They are not necessarily errors but are merely scenarios where an unexpected event has occurred. An exception can be thrown explicitly as a result of an anticipated event to bullet-proof an application from adversely affecting other applications or to provide a robust user experience.

Once a Web application is in production, exceptions must be logged in a meaningful way so that developers can analyze and troubleshoot the issues later, without having to witness the issues first-hand. Unattended monitoring exists to help monitor and track application issues and performance in the production environment. The following sections focus on how you can use unattended monitoring as part of an exception management strategy for the production environment.

Detecting Exceptions

The .NET Framework supports structured exception handling for all .NET languages. Structured exception handling provides a controlled structure to detect and handle exceptions raised during application execution. Using the try, catch, and finally code blocks can prevent exceptions in portions of the code from affecting other portions of the application. The structure of the code blocks is as follows :

 Try     'executable code with potential exceptions Catch [  Exception Class  ]     'code to handle a specific exception.     'there can be mulitple catch code blocks, each to handle a different exception Finally     'code used for cleanup, this code is always executed     ' independent of whether or not an exception is thrown 

You should not use exceptions to control the normal flow of an application. For example, the GasLaw.aspx page has the potential to have a divide by 0 exception. Because that is caused by an invalid user input, we have implemented code to check and handle this scenario without having to use exception handling. If exceptions are incorporated as part of the normal flow, the code will become unreadable and unmanageable.

It is good practice to catch exceptions as soon as possible. If the application cannot find a Catch block to handle the exception, then it checks the Catch statements in the outer exception handlers, progressing through the entire call stack until a match is found. If it cannot find any, it raises the exception all the way to the initial caller, usually the user interface application. In the case of ASP.NET, you can design robust error handling at the page or application level, but it is still good practice to avoid having unhandled exceptions migrate up the call stack.

Filtering Exceptions

You can filter exceptions based on the exception type with the Catch exception blocks. For example, the Database class in the AspNetChap8 project employs many methods from the SQL data provider. In the GetProdList() function, the exception handling handles SQL exceptions differently from other exceptions with the following code:

 Catch SQLExp As SqlException        Return (New DataSet()) Catch e As Exception        Throw New Exception("Error: "& e.Source & ": "& e.Message) Finally        ' Close the SQL connection (DataSet is disconnected)        If m_sqlConn.State = ConnectionState.Open Then m_sqlConn.Close() End Try 

Depending on the requirements of your application, each specific exception can have its own processing code.

You can filter SqlException, IOException, and other specific exceptions as part of your exception handling. This not only allows you to customize your handling for these specific exceptions, but it also allows you to display meaningful information about the type of exception encountered .

Best Practices for Throwing Exceptions

Throwing exceptions is always expensive (because so much information gets passed, and you are delegating). As such, you should throw an exception only when additional intervention is required and, even then, decide if you need to throw the whole exception or can raise an error with limited information.

If it is possible for your component to handle an exception internally, it should do so. Throwing unnecessary exceptions increases the chance that the calling component will not handle the exception and instead propagate the error up the call stack. You should not use exceptions as a means of communication between components . You should use events instead.

If, however, you do need to throw an exception up the call stack, then you have three ways to propagate the exception:

  • Automatic propagation: Ignore the exception and allow it to move up the call stack until it reaches a Catch block that matches the exception.

  • Catch and rethrow the propagation: Catch the exception and perform any tasks needed within the current method. Then throw the exception up the call stack.

  • Catch, wrap, and throw the wrapped exception: Catch the exception and perform any tasks needed within the current method. Then wrap the exception inside another exception with more meaning to the caller and throw the wrapped exception to the caller.

If you choose to generate custom exceptions within your component, be sure to document them so that developers using your component will best be able to handle them. The documentation should include a description of the exception, the conditions in which the exception will likely occur, suggested ways for resolving the error condition, and any error codes or additional information that the exception returns.

Managing Unhandled Exceptions in ASP.NET

In an ASP.NET application, an unhandled exception can propagate to the Web page itself. When this occurs, ASP.NET employs two events to handle exceptions that reach the boundary of the application.

  • Page_Error: Page-level event to handle exceptions on an individual page

  • Application_Error: Application-level event to handle exceptions propagated from any page in the application

At the page level, the Page base class exposes a Page_Error() event handler, which you can override in your pages. This handler is called whenever an unhandled exception is thrown at runtime. To override the Page_Error() handler, simply add a Page_Error() subroutine to the page's code-behind file:

 Sub Page_Error(ByVal Source As Object, ByVal E As EventArgs)    ...... End Sub 

The application-level event handler for unhandled exceptions is the Application_Error () subroutine, which is located in the Global.asax file. This handler is a last resort destination for unhandled exceptions. For this reason, the handler code should log the exception information, send notifications, and perform any other necessary actions before gracefully returning an error message to the user:

 Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs)     ' Fires when an error occurs    ...... End Sub 

Logging Exception Information

Exception information must be properly logged to be useful to the developer and support services. If it is not properly logged, it becomes difficult to track down the source of the exception or to extract any relevant data and trends from the information. You can log exception information and report it to one of three destinations:

  • Windows event log

  • Relational database

  • Custom log file

Each destination has its advantages and disadvantages.

The advantages of the Windows event log as a destination are as follows:

  • It is reliable.

  • It is available in Windows NT and Windows 2000.

  • It has built-in log file size management.

  • It is easy to use.

  • It is supported by most monitoring tools.

  • You can easily analyze the sequence of events within a system.

The disadvantages of the Windows event log as a destination are as follows:

  • The event log is tied to a server, so the data is not centralized if more than one server is used. An application can log to a remote server's event log, but the chance of failure is high and should be avoided.

  • Logged information can be overwritten depending on the event log configuration.

  • Improper configuration can cause log blocking if the event log is full.

The advantages of a relational database as a destination are as follows:

  • Data is centralized and accessible from multiple servers.

  • Database tools support queries and reporting.

  • You can define the structure of the log data to best meet the needs of the application.

The disadvantages of a relational database as a destination are as follows:

  • Dependent on a database, which introduces additional risk of connectivity and database health.

  • It is difficult to sync up database-logged data and application logs in the Event Viewer.

  • Most monitoring tools do not support interaction with a database.

The advantage of a custom log file as a destination is that you have flexibility in choosing the format of the log file. The disadvantages of a custom log file as a destination are as follows:

  • You have to deal with issues relating to concurrent access.

  • You have to design a method of managing log file size.

  • You must develop tools to read and administer the log file.

  • You must configure monitoring tools to read the log format.

.NET supports event logs through the System.Diagnostics namespace. To illustrate how to create a unique event log and insert logs, add the code to write to the event viewer in the application error event in Global.asax as follows:

 Imports System.Diagnostics Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs)          ' Fires when an error occurs          Dim ErrorDescription As String = Server.GetLastError.ToString          'Creation of event log if it does not exist          Dim EventLogName As String = "AspNetChap8"          If (Not EventLog.SourceExists(EventLogName)) Then              EventLog.CreateEventSource(EventLogName, EventLogName)          End If          ' Inserting into event log          Dim Log As New EventLog()          Log.Source = EventLogName          Log.WriteEntry(ErrorDescription, EventLogEntryType.Error)      End Sub 

In the application-level event handler, a log named "AspNetChap8" is created if it does not exist in the event log. If it already exists, the error entry is added to the existing list of events. When you test the ErrorSample.aspx page and get the "Resource not found" error as before, the Application_Error() event handler gets invoked and the resultant event is logged to the viewer. Figure 8-22 shows an example of a logged event as it appears in the Event Viewer utility. If the resultant event is not logged, it is likely caused by a permissions issue. Recall that Web application code is run in an ASP.NET worker process. By default, the identity of this process is a local ASPNET account. For this sample to work, the process identity must have write permissions to the event log.

click to expand
Figure 8-22: Event logged to the Event Viewer

Selecting the event will display the Event Properties dialog box that will display the exception type and description as in Figure 8-23.

click to expand
Figure 8-23: Event properties

Understanding Exception Notification

It is important to log exceptions to understand what caused them and how to resolve them. However, it is also important to notify support staff of exceptions in a timely manner. Exception information is not helpful unless it is provided to the person or group that is capable of interpreting and resolving the exception.

A common notification method is to send an email to the appropriate parties when an exception occurs. Many third-party application monitoring and log scraping tools exist that also include email and alert features to notify developers of application issues. However, it is relatively simple to implement this feature in ASP.NET. Again, you can set this up to function within the page-level error event or the application-level error event. For this example, add the email functionality to the application-level error event as follows:

 Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs)     ' Fires when an error occurs     ' event log code here     Dim mail As New MailMessage()     Dim ErrorMessage As String     Dim strSubject As String     strSubject = Request.Url.ToString & "Site Error"     ErrorMessage = "Error encountered in page "& Request.Url.ToString & ": "& _             Server.GetLastError.ToString     mail.To = "administrator@domain.com"     mail.Subject = strSubject     mail.Priority = MailPriority.High     mail.BodyFormat = MailFormat.Text     mail.Body = ErrorMessage     SmtpMail.Send(mail) End Sub 
Writing Custom Error Pages

In addition to the exception management common to all languages in the .NET Framework, ASP.NET provides some functionality to manage how an exception should be displayed to the user. If an error occurs in an ASP.NET application, a default error page is displayed. The page displays the error message, a description of the error encountered, and the requested URL. For example, the ErrorSample.aspx page generates an error by requesting an unavailable resource (see Figure 8-24).

click to expand
Figure 8-24: Default error page

If you wanted to display a more user-friendly error page, you can customize a default error page for your ASP.NET application. To set up the custom error page, follow these steps:

  1. Create an error page (in our example, ErrorPage .htm ).

  2. Update the Web.config file to set the defaultRedirect parameter in the <customErrors> directive within <system.web> .

  3. If necessary, you can also specify pages for certain HTTP error codes by using the statuscode attribute:

     <customErrors defaultRedirect=" ErrorPage.htm" mode=" On" />     <error statuscode="500" redirect="/errorpages/ServerError.htm" /> 

Besides the defaultRedirect parameter that stores the name of the custom error page, you can set the mode parameter with one of three values:

  • Off Mode: Sets ASP.NET to use its default error page for both local and remote users in case of an error.

  • On Mode: Sets ASP.NET to use the user-defined custom error page instead of its default error page for both local and remote users. If a custom error page is not specified, ASP.Net shows the error page describing how to enable remote viewing of errors.

  • RemoteOnly: The default ASP.NET error page is shown only to local users. Remote requests will first check the configuration settings for the custom error page or finally show an IIS error.

Having updated Web.config and deployed ErrorPage.htm to the Web server, going through the same test generates the page shown in Figure 8-25.

click to expand
Figure 8-25: Custom error page

This concludes the section on unattended monitoring. Central to the concept of unattended monitoring in a deployed application is the exception management strategy. In addition, applications should take advantage of the specific exception management features provided by ASP.NET.




Performance Tuning and Optimizing ASP. NET Applications
Performance Tuning and Optimizing ASP.NET Applications
ISBN: 1590590724
EAN: 2147483647
Year: 2005
Pages: 91

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