Displaying Gentle Error Messages with ASP.NET

Published 28 December 06 10:51 PM | Coding4Fun 
  Learn how to display gentler error messages when errors are encountered while developing ASP.NET applications. In this article, Stephen Walther shows you how you can modify the default ASP.NET error page so that it displays motivational sounds, messages, and pictures.
Stephen's Blog

Difficulty: Easy
Time Required: Less than 1 hour
Cost: Free
Software: Visual Web Developer 2005 Express Edition
Hardware:
Download: Download

    I fly out to companies and teach workshops on building ASP.NET applications to developers new to the ASP.NET framework. Typically a developer starts out excited to learn something new. Unfortunately, a developer’s first experience of the ASP.NET framework is often the error page -- the angry page with the yellow background and the red error message.

    When a novice developer encounters their first error message, I try to be reassuring. I explain that errors are normal and good and that an ASP.NET developer will view the error page at least half a billion times while developing a project of any reasonable complexity. After all, the mark of a good development framework is that it throws a lot of errors at you. A framework that throws a lot of errors prevents you from doing something stupid and deploying a buggy application into production.

    However, the question remains: why does the ASP.NET Framework seem so angry? Why the harsh yellow background and bold red error messages (see Figure 1)? Why can’t the error page be more gentle? In other words, why can’t the error page be more Myst than Halo?

    Figure 1 -- Angry ASP.NET Error Page

    This question brings us to the topic of this article. The nice thing about the ASP.NET Framework is that you can customize just about any aspect of the framework in any way that you want. This month’s project is to build a friendlier, gentler ASP.NET error page. Our error page will use nurturing colors such as blues and grays instead of yellows and reds. Furthermore, our custom error page will randomly display different motivational messages and pictures and play different soothing background sounds.

    The Visual Studio Installer file that accompanies this article includes a new VB.NET and C# Project Template named Friendly Errors. If you choose this template when creating a new project, the default error message page will be replaced with a custom error message page (see Figure 2).

    Figure 2 -- Gentle ASP.NET Error Page

    Handling Application Exceptions

    I should admit up front that I thought that this would be an extremely easy project. The ASP.NET Framework enables you to easily create a custom error page by adding a <customErrors> section to your application’s Web configuration (Web.config) file. For example, adding the following Web.config file to the root of your application causes a page named CustomError.aspx to be displayed when there is any error:

    <configuration>

    <system.web>

    <customErrors mode="On" defaultRedirect="~/CustomError.aspx" />

    </system.web>

    </configuration>

    Adding this configuration file to your application works great. Whenever there is an error, the user is redirected to the CustomError.aspx page automatically. You can display any message in this page that you want. For example, you can display the message “This site is currently undergoing scheduled maintenance”.

    Unfortunately, however, there is no way in the CustomError.aspx page to get information about the error that caused the redirect to the CustomError.aspx page. You can display a message, but you cannot display detailed error information.

    Therefore, in this project, I took another approach. Instead of using the <customErrors> section, I handled the Application Error event. This event is raised whenever there is any unhandled exception in an application. In other words, if any code within a page or a component raises an exception, and the code is not wrapped by a Try...Catch block, then the Application Error event is raised.

    There are two ways that you can handle the Application Error event. You can handle the event in the Global.asax file or you can handle the event by creating a custom HTTP Module. I handled the Application Error event in a module named FriendlyErrorsModule. The code for the FriendlyErrorsModule is contained in Listing 1.

    Listing 1 -- FriendlyErrorModule.cs

    using System; 
    
    using System.Web; 
    
    using System.Web.Configuration; 
    
    namespace Superexpert 
    
    { 
    
    /// <summary> 
    
    /// Handles all unhanlded exceptions in an application 
    
    /// </summary> 
    
    public class FriendlyErrorsModule : IHttpModule 
    
    { 
    
      public void Init(HttpApplication app) 
    
      { 
    
        app.Error += new EventHandler(app_Error); 
    
      } 
    
      /// <summary> 
    
      /// When debug mode is enabled, display 
    
      /// friendly error page 
    
      /// </summary> 
    
      void app_Error(object sender, EventArgs e) 
    
      { 
    
        HttpApplication app = (HttpApplication)sender; 
    
        HttpContext context = app.Context; 
    
        Exception error = context.Server.GetLastError().GetBaseException(); 
    
        context.Response.Clear(); 
    
        CompilationSection compilationConfig = (CompilationSection)WebConfigurationManager.GetWebApplicationSection("system.web/compilation"); 
    
        if (compilationConfig.Debug) 
    
          context.Server.Transfer("~/FriendlyErrors/Debug.aspx"); 
    
        else 
    
          context.Server.Transfer("~/FriendlyErrors/Public.aspx"); 
    
      } 
    
      public void Dispose() 
    
      { 
    
      } 
    
    } 
    
    } 
    
    


    Listing 1 -- FriendlyErrorModule.vb

     

    Imports System 
    
    Imports System.Web 
    
    Imports System.Web.Configuration 
    
    Namespace Superexpert 
    
    ''' <summary> 
    
    ''' Handles all unhanlded exceptions in an application 
    
    ''' </summary> 
    
    Public Class FriendlyErrorsModule 
    
    Implements IHttpModule 
    
      Public Sub Init(ByVal app As HttpApplication) Implements IHttpModule.Init 
    
        AddHandler app.Error, AddressOf app_Error 
    
      End Sub 
    
      ''' <summary> 
    
      ''' When debug mode is enabled, display 
    
      ''' friendly error page 
    
      ''' </summary> 
    
      Sub app_Error(ByVal sender As Object, ByVal e As EventArgs) 
    
        Dim app As HttpApplication = CType(sender, HttpApplication) 
    
        Dim context As HttpContext = app.Context 
    
        context.Response.Clear() 
    
        Dim compilationConfig As CompilationSection = CType(WebConfigurationManager.GetWebApplicationSection("system.web/compilation"), CompilationSection) 
    
        If (compilationConfig.Debug) Then 
    
          context.Server.Transfer("~/FriendlyErrors/Debug.aspx") 
    
        Else 
    
          context.Server.Transfer("~/FriendlyErrors/Public.aspx") 
    
        End If 
    
      End Sub 
    
      Public Sub Dispose() Implements IHttpModule.Dispose 
    
      End Sub 
    
    End Class 
    
    End Namespace 
    
    

    The class in Listing 1 implements the IHttpModule interface. This interface has two methods that you must implement: Init() and Dispose(). In Listing 1, the Init() method is used to wire the Application Error event to a handler named app_Error.

    The app_Error handler checks whether debugging is enabled in the Web.config file. If debugging is enabled, then the user is transferred to a page named Debug.aspx whenever there is an error. Otherwise, if debugging is not enabled, the user is transferred to a page named Public.aspx.

    Creating a Custom Error Page

    The last part of this project involved creating the error page itself. The custom error page is named Debug.aspx. This page does a number of different things.

    First, the page displays detailed error information. To get detailed error information, you must create an instance of the System.Diagnostics.StackTrace class. You can take advantage of the StackTrace class to get the name of the page associated with the error as well as the source code that caused the error.

    The Friendly Errors Project Template includes a class named FriendlyError. This class includes methods for retrieving detailed error information. the Debug.aspx page uses the FriendlyError class behind the scenes.

    The Debug.aspx page also displays a random picture. You can modify the pictures that the Debug.aspx page displays by modifying the contents of the FriendlyErrors/Pictures folder. The Debug.aspx page randomly displays one picture from this folder.

    You can add any pictures to this folder that you want. For example, you can add baby pictures and motivational pictures of your favorite foods or persons.

    The Debug.aspx page also displays a random motivational message. You can modify the motivational messages displayed by the Debug.aspx page by modifying the FriendlyErrors/Messages/Messages.xml file. This XML file contains a list of <message> elements that contain each of the motivational messages.

    Finally, the Debug.aspx page plays a background sound. The page uses the <object> tag so that the background sound will play correctly in both Microsoft Internet Explorer and Mozilla Firefox. You can customize the background sounds used by the Debug.aspx page by modifying the contents of the FriendlyErrors/Sounds folder. The Debug.aspx page randomly plays a sound from this folder.

    Again, you can add any sound file to this folder that you please. By default, the folder contains soothing chime sounds. If you want, you could add drop other motivational sounds into this folder such as Homer Simpson saying Doh!

    Testing the Custom Error Page

    You’ll see the custom error page, Debug.aspx, whenever there is any unhandled exception in your project. Don’t worry, unless you are the perfect programmer, you’ll see the Debug.aspx pretty quickly when developing an application when using the Friendly Errors Project Template.

    If you insist on intentionally creating an error in your application, then you can use the page in Listing 2. Both the C# and VB.NET versions of this page cause an exception that causes the Debug.aspx page to be displayed.

    Listing 2 -- BadPage.aspx (C#)

    <%@ Page Language="C#" %> 
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
    
    <script runat="server"> 
    
    void Page_Load() 
    
    { 
    
      int zero = 0; 
    
      Response.Write(1/zero); 
    
    } 
    
    </script> 
    
    <html xmlns="http://www.w3.org/1999/xhtml" > 
    
    <head runat="server"> 
    
    <title>Bad Page</title> 
    
    </head> 
    
    <body> 
    
    <form id="form1" runat="server"> 
    
    <div> 
    
    I am a bad page 
    
    </div> 
    
    </form> 
    
    </body> 
    
    </html> 
    
    

    Listing 2 -- BadPage.aspx (VB.NET)

    <%@ Page Language="VB" %> 
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
    
    <script runat="server"> 
    
    Sub Page_Load() 
    
      Dim Blow 
    
      Blow.Up() 
    
    End Sub 
    
    </script> 
    
    <html xmlns="http://www.w3.org/1999/xhtml" > 
    
    <head runat="server"> 
    
    <title>Bad Page</title> 
    
    </head> 
    
    <body> 
    
    <form id="form1" runat="server"> 
    
    <div> 
    
    I am a bad page 
    
    </div> 
    
    </form> 
    
    </body> 
    
    </html> 
    
    

    Conclusion

    The purpose of this month’s column is to demonstrate that you can customize just about any aspect of the ASP.NET Framework: including the default error page. If you are going to spend countless hours staring at one particular page (and I’ve spent an embarrassing number of hours of my life staring at the error page) then you might as well make the experience pleasant.

    Filed under: ,

    Comment Notification

    If you would like to receive an email when updates are made to this post, please register here

    Subscribe to this post's comments using RSS

    Comments

    # Robert McLaws said on December 29, 2006 2:07 AM:

    This is really cool, but why not make it an item template, instead of a project template? If you've already got a project starting from the ASP.NET AJAX project, the download doesn't help much.

    But this is cool, thanks!

    # wenchingchua said on December 29, 2006 7:37 AM:

    That is really interesting. Thanks for sharing :) I never think of having sounds than showing nice messages :P

    # Kit West said on December 29, 2006 12:06 PM:

    The gentle message is definitely nicer than the angry one, but if there's truly a fault in the site, I'd like to know about it as a developer, not show it to users. We display something generic like, "An error was encountered and logged, and the operation was canceled -- sorry for the inconvenience. Please contact IT if this causes an urgent problem. Thank you." I get the user id, date/time, stack trace, along with parameter values and other context info, from my database (more accessible than system log).

    # anushka K Rajasingha said on September 29, 2007 2:47 AM:

    That is really interesting. Thanks for sharing

    # Meenakshi Dhar said on January 16, 2008 12:15 AM:

    The download link is not working.. Can anybody please tell me from where I can download this example...

    # Coding4Fun said on January 16, 2008 12:39 PM:

    Link is on Channel9

    http://channel9.msdn.com/Photos/ZippedFiles/269023_FriendlyErrors.zip is the direct link

    # Justas Birgiolas said on March 4, 2008 5:31 PM:

    If you don't want to install the templates, you can look at the individual files. Once you run the vsi file from the archive, on the first screen look for a blue "View files in Windows Explorer" link. This will let you see and modify the individual files.

    Leave a Comment

    (required) 
    (optional)
    (required) 
    Page view tracker