Recipe 8.5. Displaying User-Friendly Error Messages


Problem

You want the event-handling methods described in this chapter to write detailed messages to an error log for use in debugging your application, but you want to display friendly, informative messages to the user.

Solution

Create a custom exception class that includes a property to hold the user-friendly message, and when an error occurs, instantiate a new exception object of the custom type in the Catch block of your error-handling code, set the property of the exception to the desired message, and throw the new exception.

Use the .NET language of your choice to create the custom exception class by deriving from System.ApplicationException and adding a property to hold the userfriendly message, giving it a name like userFriendlyMessage.

In the code-behind for the ASP.NET pages of your application that need to perform error handling, use the .NET language of your choice to:

  1. In the Catch block of methods where informative messages are useful, instantiate a new exception object of your custom class type, set the userFriendlyMessage property to the desired message, and throw the new exception.

  2. In the Application_Error event handler, write the detailed information provided by the exception object to the event log and display the message contained in the userFriendlyMessage property of the exception on a common error message page.

The custom exception class we've created to demonstrate this solution is shown in Examples 8-10 (VB) and 8-11 (C#). The code showing how to create the new exception is shown in Examples 8-12 (VB) and 8-13 (C#). The code for the Application_Error event handler is shown in Examples 8-14 (VB) and 8-15 (C#). (Because the .aspx file for this example contains nothing related to the error handling, it is not included in this recipe.)

Discussion

The first step to providing user-friendly messages with your exceptions is to create a new class that inherits from System.ApplicationException. (The System.ApplicationException class extends System.Exception but adds no new functionality. It is meant to be used to differentiate between exceptions defined by applications and those defined by the system.)

If the custom exception classes are intended for use only in your current application, the classes should be placed in the App_Code folder of your application. If you are using Visual Studio 2005, it will offer to create the folder and place the class in it for you.

If the custom exception classes are intended to be used in multiple applications, a separate Class project should be created. The assembly created by the Class project should then be placed in the bin folder of your project and a reference added to the assembly to allow using the classes in your application.


You then need to add a property to the class to support the user-friendly message. The last step in creating the new exception class is to create a constructor that will create the base exception, by calling the base class constructor with the raw message and a reference to the inner exception, and then to set the user-friendly message. Examples 8-10 (VB) and 8-11 (C#) show how we have implemented these steps.

The new exception class is put to use in the Catch block of your code by creating an instance of the new exception class, passing it the original message, a reference to the exception, and the desired user-friendly message. The reference to the original exception is passed to preserve the linked list of exceptions. In this case, your new exception will point to the original exception by using the inner property of the new exception. After the new exception class is created, it is thrown. Examples 8-12 (VB) and 8-13 (C#) illustrate a sample Catch block.

As shown in Examples 8-14 (VB) and 8-15 (C#), our sample Application_Error event handler writes detailed information to the event log and then displays the message contained in the userFriendlyMessage property of the exception. This example event code is a variation of the event code described in Recipe 8.3, modified to check if the exception being processed has a user-friendly message to use instead of the raw exception message.

This recipe's approach can be extended many ways to suit your needs. For example, the custom exception class could contain a nextPage property set to pass information on where the user should be taken after reviewing the error message.

See Also

Recipe 8.3

Example 8-10. Custom exception class with user-friendly message property (.vb)

 Option Explicit On Option Strict On Namespace ASPNetCookbook.VBExamples ''' <summary> ''' This class provides an exception class with support for a user- ''' friendly message ''' </summary> Public Class CH08FriendlyExceptionVB Inherits System.ApplicationException 'private copy of user friendly message Private mUserFriendlyMessage As String = "" '''*********************************************************************** ''' <summary> ''' Provides access to the message to be displayed to the user-friendly ''' message. ''' </summary> Public Property userFriendlyMessage( ) As String Get Return (mUserFriendlyMessage) End Get Set(ByVal Value As String) mUserFriendlyMessage = Value End Set End Property 'userFriendlyMessage '''*********************************************************************** ''' <summary> ''' Provides a constructor supporting an error message, a reference to ''' the exception that threw this exeception, and a user-friendly ''' message for the exception ''' </summary> Public Sub New(ByVal message As String, _   ByVal inner As Exception, _   ByVal userFriendlyMessage As String) 'call base class constructor. NOTE: This must be the first line in 'this constructor MyBase.New(message, inner) mUserFriendlyMessage = userFriendlyMessage End Sub 'New End Class 'CH08FriendlyExceptionVB End Namespace 

Example 8-11. Custom exception class with user-friendly message property (.cs)

 using System; namespace ASPNetCookbook.CSExamples { /// <summary> /// This class provides an exception class with support for a user- /// friendly message public class CH08FriendlyExceptionCS : System.ApplicationException { // private copy of user friendly message private String mUserFriendlyMessage = ""; ///*********************************************************************** /// <summary> /// Provides access to the message to be displayed to the user-friendly /// message. /// </summary> public String userFriendlyMessage { get { return(mUserFriendlyMessage); } set { mUserFriendlyMessage = value; } } // userFriendlyMessage ///*********************************************************************** /// <summary> /// Provides a constructor supporting an error message, a reference to /// the exception that threw this exeception, and a user-friendly /// message for the exception /// </summary> public CH08FriendlyExceptionCS(String message,  Exception inner,  String userFriendlyMessage) :   base(message, inner) { mUserFriendlyMessage = userFriendlyMessage; } } // CH08FriendlyExceptionCS } 

Example 8-12. Creation of new custom exception (.vb)

 '''*********************************************************************** ''' <summary> ''' This routine provides the event handler for the page load event. It ''' is responsible for initializing the controls on the page. ''' </summary> ''' ''' <param name="sender">Set to the sender of the event</param> ''' <param name="e">Set to the event arguments</param> Private Sub Page_Load(ByVal sender As Object, _  ByVal e As System.EventArgs) Handles Me.Load Dim values As Hashtable = Nothing Try 'add a key/value pair to the hashtable without first creating 'the hashtable which will cause a null exception error values.Add("Key", "Value") Catch exc As Exception Throw New CH08FriendlyExceptionVB(exc.Message, _   exc, _   "The application is currently " &_   "experiencing technical " &_   "difficulties … " &_   "Please try again later")     End Try End Sub 'Page_Load 

Example 8-13. Creation of new custom exception (.cs)

 ///*********************************************************************** /// <summary> /// This routine provides the event handler for the page load event. /// It is responsible for initializing the controls on the page. /// </summary> /// /// <param name="sender">Set to the sender of the event</param> /// <param name="e">Set to the event arguments</param> protected void Page_Load(object sender, EventArgs e) { Hashtable values = null; try { // add a key/value pair to the hashtable without first creating // the hashtable which will cause a null exception error values.Add("Key", "Value"); } catch (Exception exc) { throw new CH08FriendlyExceptionCS(exc.Message,   exc,   "The application is currently " +   "experiencing technical " +   "difficulties … " +   "Please try again later");     } } // Page_Load 

Example 8-14. Application_Error code for displaying a user-friendly message (.vb)

 '''*********************************************************************** ''' <summary> ''' This routine provides the event handler for the application error ''' event. It is responsible for processing errors at the application ''' level. ''' </summary> ''' ''' <param name="sender">Set to the sender of the event</param> ''' <param name="e">Set to the event arguments</param> Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs) Const EVENT_LOG_NAME As String = "Application" Dim lastException As Exception Dim userFriendlyException As CH08FriendlyExceptionVB Dim Log As EventLog Dim message As String 'get the last error that occurred lastException = Server.GetLastError( ) 'create the error message from the message in the last exception along 'with a complete dump of all of the inner exceptions (all exception 'data in the linked list of exceptions) message = lastException.Message &_ vbCrLf &vbCrLf &_ lastException.ToString( ) 'Insert error information into the event log Log = New EventLog Log.Source = EVENT_LOG_NAME Log.WriteEntry(message, _ EventLogEntryType.Error) 'perform other notifications, etc. here 'check to if the exception has a user friendly message If (TypeOf (lastException) Is CH08FriendlyExceptionVB) Then 'exception has a user friendly message userFriendlyException = CType(lastException, _   CH08FriendlyExceptionVB) message = userFriendlyException.userFriendlyMessage Else 'exception does not have a user friendly message to just 'output the raw message message = lastException.Message End If 'clear the error and redirect to the page used to display the 'error information Server.ClearError( ) Server.Transfer("CH08DisplayErrorVB.aspx" &_ "?PageHeader=Error Occurred" &_ "&Message1=" &message &_ "&Message2=" &_ This exception used a user friendly mesage") End Sub 'Application_Error 

Example 8-15. Application_Error code for displaying a user-friendly message (.cs)

 ///*********************************************************************** /// <summary> /// This routine provides the event handler for the application error /// event. It is responsible for processing errors at the application /// level. /// </summary> /// /// <param name="sender">Set to the sender of the event</param> /// <param name="e">Set to the event arguments</param> protected void Application_Error(Object sender, EventArgs e) { const String EVENT_LOG_NAME = "Application"; Exception lastException = null; CH08FriendlyExceptionCS userFriendlyException = null; EventLog log = null; String message = null; // get the last error that occurred lastException = Server.GetLastError( ); // create the error message from the message in the last exception along // with a complete dump of all of the inner exceptions (all exception // data in the linked list of exceptions) message = lastException.Message +   "\r\r" +   astException.ToString( ); // Insert error information into the event log log = new EventLog( ); log.Source = EVENT_LOG_NAME; log.WriteEntry(message, EventLogEntryType.Error); // perform other notifications, etc. here // check to if the exception has a user friendly message if (lastException.GetType( ) == typeof(CH08FriendlyExceptionCS)) { // exception has a user friendly message userFriendlyException = (CH08FriendlyExceptionCS)(lastException); message = userFriendlyException.userFriendlyMessage; } else { // exception does not have a user friendly message to just // output the raw message message = lastException.Message; } // clear the error and redirect to the page used to display the // error information Server.ClearError( ); Server.Transfer("CH08DisplayErrorCS.aspx" + "?PageHeader=Error Occurred" + "&Message1=" + message + "&Message2=" + "This exception used a user friendly mesage"); } // Application_Error 



ASP. NET Cookbook
ASP.Net 2.0 Cookbook (Cookbooks (OReilly))
ISBN: 0596100647
EAN: 2147483647
Year: 2003
Pages: 202

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