New Document
ASP.NET Error Handling

ASP.NET applications must be able to handle errors that occur during execution in a consistent manner. ASP.NET uses the common language runtime (CLR), which provides a way of notifying applications of errors in a uniform way. When an error occurs, an exception is thrown. An exception is any error, condition, or unexpected behavior that an application encounters.


In the .NET Framework, an exception is an object that inherits from the System.Exception class. An exception is thrown from an area of code where a problem has occurred. The exception is passed up the call stack to a place where the application provides code to handle the exception. If the application does not handle the exception, the browser is forced to display the error details.


As a best practice, handle errors in at the code level in Try/Catch/Finally blocks within your code. Try to place these blocks so that the user can correct problems in the context in which they occur. If the error handling blocks are too far away from where the error occurred, it becomes more difficult to provide users with the information they need to fix the problem.


In this tutorial, you will modify the Wingtip Toys sample application to include error handling and error logging. Error handling will allow the application to gracefully handle errors and display error messages accordingly. Error logging will allow you to find and fix errors that have occurred. This tutorial builds on the previous tutorial "URL Routing" and is part of the Wingtip Toys tutorial series.


What you'll learn:


How to add global error handling to the application's configuration.

How to add error handling at the application, page, and code levels.

How to log errors for later review.

How to display error messages that do not compromise security.

How to implement Error Logging Modules and Handlers (ELMAH) error logging.


Error handling in ASP.Net has three aspects:


  1. Tracing - tracing the program execution at page level or application level.

  2. Error handling - handling standard errors or custom errors at page level or application level

  3. Debugging - stepping through the program, setting break points to analyze the code

In this tutorial, we are going to discuss tracing and error handling and we will look into debugging in the next tutorial.

To understand the concepts, create the following sample application. It has a label control, a dropdown list and a link. The dropdown list loads an array list of famous quotes and the selected quote is shown in the label below. It also has a hyperlink which has a nonexistent link.

ASP.NET applications must be able to handle errors that occur during execution in a consistent manner. ASP.NET uses the common language runtime (CLR), which provides a way of notifying applications of errors in a uniform way. When an error occurs, an exception is thrown. An exception is any error, condition, or unexpected behavior that an application encounters.

In the .NET Framework, an exception is an object that inherits from the System.Exception class. An exception is thrown from an area of code where a problem has occurred. The exception is passed up the call stack to a place where the application provides code to handle the exception. If the application does not handle the exception, the browser is forced to display the error details.

As a best practice, handle errors in at the code level in Try/Catch/Finally blocks within your code. Try to place these blocks so that the user can correct problems in the context in which they occur. If the error handling blocks are too far away from where the error occurred, it becomes more difficult to provide users with the information they need to fix the problem.


Exception Class

The Exception class is the base class from which exceptions inherit. Most exception objects are instances of some derived class of the Exception class, such as the SystemException class, the IndexOutOfRangeException class, or the ArgumentNullException class. The Exception class has properties, such as the StackTrace property, the InnerException property, and the Message property, that provide specific information about the error that has occurred.

Exception Inheritance Hierarchy

The runtime has a base set of exceptions deriving from the SystemException class that the runtime throws when an exception is encountered. Most of the classes that inherit from the Exception class, such as the IndexOutOfRangeException class and the ArgumentNullException class, do not implement additional members. Therefore, the most important information for an exception can be found in the hierarchy of exceptions, the exception name, and the information contained in the exception.

Exception Handling Hierarchy

In an ASP.NET Web Forms application, exceptions can be handled based on a specific handling hierarchy. An exception can be handled at the following levels:

Application level

Page level

Code level

When an application handles exceptions, additional information about the exception that is inherited from the Exception class can often be retrieved and displayed to the user. In addition to application, page, and code level, you can also handle exceptions at the HTTP module level and by using an IIS custom handler. Application Level Error Handling

You can handle default errors at the application level either by modifying your application's configuration or by adding an Application_Error handler in the Global.asax file of your application.

You can handle default errors and HTTP errors by adding a customErrors section to the Web.config file. The customErrors section allows you to specify a default page that users will be redirected to when an error occurs. It also allows you to specify individual pages for specific status code errors.

<%@ Page Language="C#" 
         AutoEventWireup="true" 
         CodeBehind="Default.aspx.cs" 
         Inherits="errorhandling._Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Tracing, debugging and error handling</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Label ID="lblheading" runat="server" 
            Text="Tracing, Debuggin and Error Handling">
        </asp:Label>
        <br />
        <br />
        <asp:DropDownList ID="ddlquotes" 
        runat="server" AutoPostBack="True" 
        onselectedindexchanged="ddlquotes_SelectedIndexChanged">
        </asp:DropDownList>
        <br />
        <br />
        <asp:Label ID="lblquotes" runat="server">
        </asp:Label>
        <br />
        <br />
        <asp:HyperLink ID="HyperLink1" runat="server" 
        NavigateUrl="mylink.htm">Link to:</asp:HyperLink>
    </div>
    </form>
</body>
</html>

The code behind file:

public partial class _Default : System.Web.UI.Page
{
   protected void Page_Load(object sender, EventArgs e)
   {
      if (!IsPostBack)
      {
         string[,] quotes = 
        {
        {"Imagination is more important than Knowledge.", 
         "Albert Einsten"},
        {"Assume a virtue, if you have it not",
         "Shakespeare"},
        {"A man cannot be comfortable without his own 
         approval", "Mark Twain"},
        {"Beware the young doctor and the old barber",
         "Benjamin Franklin"},
       {"Whatever begun in anger ends in shame",
         "Benjamin Franklin"}
     };
     for (int i=0; i<quotes.GetLength(0); i++)
        ddlquotes.Items.Add(new ListItem(quotes[i,0], 
        quotes[i,1]));
     }
   }
   protected void ddlquotes_SelectedIndexChanged(object sender, 
                                                 EventArgs e)
   {
     if (ddlquotes.SelectedIndex != -1)
     {
       lblquotes.Text = String.Format("{0}, Quote: {1}", 
          ddlquotes.SelectedItem.Text, ddlquotes.SelectedValue);
     }
   }
}
Tracing:

To enable page level tracing, you need to modify the Page directive and add a Trace attribute as:

<%@ Page Language="C#" AutoEventWireup="true" 
            CodeBehind="Default.aspx.cs"
            Inherits="errorhandling._Default"
            Trace ="true" %>

Now when you run the file, you get the tracing information:

Tracing Info

It provides the following information at the top:

  • Session ID

  • Status Code

  • Time of Request

  • Type of Request

  • Request and Response Encoding

The status code sent from the server, each time the page is requested shows the name and time of error if any. The following table shows the common HTTP status codes :

NumberDescription
Informational (100 - 199)
100Continue
101Switching protocols
Successful (200 - 299)
200OK
204No content
Redirection (300 - 399)
301Moved permanently
305Use proxy
307Temporary redirect
Client Errors (400 - 499)
400Bad request
402Payment required
404Not found
408Request timeout
417Expectation failed
Server Errors (500 - 599)
500Internal server error
503Service unavailable
505HTTP version not supported

Under the top level information is the Trace log, which provides details of page life cycle. It provides elapsed time in seconds since the page was initialized.

Tracing Info2

The next section is control tree, which lists all controls on the page in a hierarchical manner:

Tracing Info3

Last in the Session and Application state summaries, cookies and headers collections, followed by list of all server variables.

The Trace object allows you to add custom information to the trace output. It has two methods to accomplish this: the Write method and the Warn method.

Change the Page_Load event handler to check the Write method:

protected void Page_Load(object sender, EventArgs e)
{
   Trace.Write("Page Load");
   if (!IsPostBack)
   {
      Trace.Write("Not Post Back, Page Load");
      string[,] quotes = 
.......................

Run to observe the effects:

Tracing Info4

To check the Warn method, let us forcibly enter some erroneous code in the selected index changed event handler:

try
{
   int a = 0;
   int b = 9 / a;
}
catch (Exception e)
{
   Trace.Warn("UserAction", "processing 9/a", e);
}

Try-Catch is a C# programming construct. The try block holds any code that may or may not produce error and the catch block catches the error. When the program is run, it sends the warning in the trace log.

Tracing Info5

Application level tracing applies to all the pages in the web site. It is implemented by putting the following code lines in the web.config file:

<system.web>
<trace enabled="true" />
</system.web>
Error Handling:

Although ASP.Net can detect all runtime errors, still some subtle errors may still be there. Observing the errors by tracing is meant for the developers, not for the users.

Hence, to intercept such occurrence, you can add error handing settings in the web.config file of the application. It is application wide error handling. For example, you can add the following lines in the web.config file:

<configuration>
	<system.web>
	<customErrors mode="RemoteOnly"
		defaultRedirect="GenericErrorPage.htm">
<error statusCode="403" redirect="NoAccess.htm"	/>
<error statusCode="404" redirect="FileNotFound.htm" />
</customErrors>
</system.web>
<configuration>

The <customErrors> section has the possible attributes:

  • Mode: It enables or disables custom error pages. It has the three possible values:

    • On: displays the custom pages.
    • Off: displays ASP.Net error pages (yellow pages)
    • remoteOnly: displays custom errors to client, display ASP.Net errors locally
  • defaultRedirect: It contains the URL of the page to be displayed in case of unhandled errors.

To put different custom error pages for different type of errors, the <error> sub tags are used, where different error pages are specified, based of the status code of the errors.

To implement page level error handling, the Page directive could be modified:

<%@ Page Language="C#" AutoEventWireup="true" 
            CodeBehind="Default.aspx.cs"
            Inherits="errorhandling._Default"
            Trace ="true" 
            ErrorPage="PageError.htm" %>

Because ASP.Net Debugging is an important subject in itself so we would discuss it in ASP.Net - Debugging tutorial separately.



Previous                                                                                                                                                       Next

Back to Top