Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Exception handling in C# and ASP.NET

0.00/5 (No votes)
27 Oct 2006 1  
Exception handling on basis of ASP.NET and C#
This article provides insight about exception handling on the basis of ASP.NET and C# as code behind.

Introduction

Exception handling is an in-built mechanism in .NET Framework to detect and handle run time errors. Exceptions are defined as anomalies that occur during the execution of a program. The .NET Framework provides a rich set of standard exceptions that are used during exceptions handling. Exception handling is one of the major features provided by .NET. There might be various reasons to handle exception, this can be caused due to improper user inputs, improper design logic or system errors. In this scenario, if applications do not provide a mechanism to handle these anomalies, then there might be cases in which the application may crash. .NET run time environment provides a default mechanism, which terminates the program execution.

This article provides insight about exception handling on the basis of ASP.NET and C# as code behind.

ASP.NET Exception Handling

In ASP.NET, exception handling is achieved using the Try - Catch - Finally block. All the three are ASP.NET keywords and are used do exception handling. The try block encloses the statements that might throw an exception whereas catch block handles any exception if one exists. The finally block can be used for doing any clean up process. Any general ASP.NET exception forces the application to terminate without allowing the code to continue executing, resulting in an error page.

try
{
    // Statements that are can cause exception
}
catch(Type x)
{
    // Statements to handle exception
}
finally
{
    // Statement to clean up
}

try-catch-finally block in ASP.NET:

<Script runat=server>
Public Page_Load(sender As Object, e As EventArgs)
{
try
{
    // Statements that are can cause exception
}
catch(Type x)
{
    // Statements to handle exception
}
finally
{
    // Statement to clean up
}
}

</Script>

When an error occurs, we get an instance of exception or possibly a derived, more specialized instanced, such as a NoNullAllowedException when attempting to insert a null value into a SQL table row that does not allow null value.

Exceptions provide us with detailed information about what occurred; for example stack trace, inner exception details, message and additional details.

Unhandled Exceptions

When some of exceptions are not handled in Try ? Catch ? Finally block of ASP.NET, still there are ways provided by the framework facilities for handling the exception through two events:

Page_Error
Application_Error   

Page and Application Error Event Handlers

This is very useful in cases where an exception is unexpected and does not occur within the bounds of a Try/Catch/Finally block. These exceptions are usually an indicator that something is substantially wrong with the application. That is, some abnormal exception has occurred and no means are provided to handle exception. In this case, there is the option to deal with the error at either the Page or Application level.

If the exception is dealt at Page level, the details needs to be provided for the Page_Error event:

C# way of implementation is as follows:

public void Page_Error(Object sender, EventArgs e)

{
    // Implementation here
} 

This event is implemented within the Page that the error may occur within.

Alternatively, the Application_Error event can be used to handled the above scenario. Unlike the Page_Error event, the Application_Error event is implemented in global.asax and any unhandled exception that occurs within our application raises from this event.

C# way of implementation is as follows:

public void Application_Error(Object sender, EventArgs e)

{
    // Implementation here
}

Working with Custom Errors

The default settings that is available in machine.config is as follows:

<customErrors mode="RemoteOnly"/>

The mode attribute has three options that can be used for customizing the error:

  1. RemoteOnly: When an unhandled exception occurs, localhost that is where the web pages are placed will see the ASP.NET error page, which includes compilation details and accessibility to the full source. However, remote users, i.e., the client browsers are shown a different ASP.NET error page that simply lets them know an error occurred. No other details are provided. If any custom error page is available, then this page will be displayed to the remote user when any exception occurs.
  2. On: The detailed ASP.NET error page is never shown, even to local users. If a custom error page is available, it is displayed.
  3. Off: The detailed ASP.NET error page is always displayed, even if a custom error page exists.

In addition to the mode settings, there are several other configuration options for the customErrors section of the configuration.

  1. defaultRedirect: A custom error page that client is redirected to when an error occurs. For example, if a error page designed with name errorPage.aspx, then the following configuration entry in web.config for an ASP.NET application has to made for obtaining the desired results:
<customErrors mode="On" defaultRedirect=" errorPage.aspx"/>

Whenever an unhandled exception occurs within our application, the user is redirected to errorPage.aspx, which provides a user-friendly error message.

Special Case

This option provides a special case for the custom error page depending upon the HTTP status code. For example, a custom error page if the request attempts to access a page does not exist (HTTP 404). Following configuration element need to be put that can be nested in <customErrors>, <error> as:

<customErrors mode="On" defaultRedirect=" errorPage.aspx">
<error statusCode="404" redirect=" errorPage404.aspx"/>
</customErrors>

Now, whenever a request is made for a document that cannot be located, we can send the request to a custom page.

C# Exception Handling

In C#, exception handling is achieved using the try ? catch ? finally block. All the three are C# keywords that are used do exception handling. The try block encloses the statements that might throw an exception whereas catch block handles any exception if one exists. The finally block can be used for doing any clean up process.

try
{
    // Statements that are can cause exception
}
catch(Type x)
{
    // Statements to handle exception
}
finally
{
    // Statement to clean up
}

try-catch-finally Block in C#

As mentioned earlier, any exception that occurs inside the try block, transfers control to the appropriate catch block and later to the finally block. In C#, both catch and finally blocks are optional. The try block can exist either with one or more catch blocks or a finally block or with both catch and finally blocks.

In cases when there is no exception inside the try block, the control directly transfers to finally block. So the statements inside the finally block are always executed. C# exceptions are objects of the type Exception. The Exception base class is used for any exceptions in C#. Some of the standard exceptions derived of Exception class are DivideByZeroException, ArgumentException, etc.

Example of Un-Handled Exception

The following program will encounter an exception when executed. At the time of compilation, there will be no error caused. In the following code, division by zero exception occurs. The division by zero is a runtime anomaly and program terminates with an error message.

//C#: Exception Un - Handled
using System;
class UnHandledException
{
    public static void Main()
    {
        int x = 0;
        int intTemp = 100/x;
        Console.WriteLine(intTemp);
    }
} 

Any un-handled exceptions find the appropriate block where it is handled, if they are no appropriate blocks, then the default .NET runtime will terminate the execution of the entire program.

Example of Handled Exception

The above program can be modified in the following manner to track the exception. You can see the usage of standard DivideByZeroException class.

//C#: Exception Handling

using System;
class HandledException
{
    public static void Main()
    {
        int x = 0;
        int intTemp = 0;
        try
        {
            intTemp = 100/x;
            Console.WriteLine(?Program terminated before this statement?);
        }
        catch(DivideByZeroException de)
        {
            Console.WriteLine("Division by Zero occurs");
        }
        finally
        {

            Console.WriteLine("Result is {0}", intTemp);
         }
    }
} 

In the above example, the program ends in an expected way instead of program termination. At the time of exception, program control passes from exception point inside the try block and enters catch blocks. As the finally block is present, so the statements inside final block are executed.

Example of Exception Unhandled in Catch Block

As in C#, the catch block is optional. The following program is perfectly legal in C#.

//C#: Exception Handling without catch block
using System;
class HandledException
{
    public static void Main()
    {
        int x = 0;
        int intTemp = 0;
        try
        {
            intTemp = 100/x;
             Console.WriteLine("Not executed line");
        }
        finally
        {
            Console.WriteLine("Inside Finally Block");
        }
        Console.WriteLine("Result is {0}", intTemp);
    }
}

The above example will produce no exception at the compilation time but the program will terminate due to unhandled exception. But the thing that is of great interest to all is that before the termination of the program, the final block is executed.

Example of Multiple Catch Blocks

A try block can throw multiple exceptions, that can handle by using multiple catch blocks. The important point here is that more specialized catch block should come before a generalized one. Otherwise, the compiler will show a compilation error.

//C#: Exception Handling: Multiple catch

using System;
class HandledException
{
    public static void Main()
    {
        int x = 0;
        int intTemp = 0;
        try
        {
            intTemp = 100/x;
            Console.WriteLine("Not executed line");
        }
        catch(DivideByZeroException de)
        {
            Console.WriteLine("DivideByZeroException" );
        }
        catch(Exception ee)
        {
            Console.WriteLine("Exception" );
        }
        finally
        {
            Console.WriteLine("Finally Block");
        }
        Console.WriteLine("Result is {0}", intTemp);
    }
} 

Example of Catching all Exceptions

By providing a catch block without brackets or arguments, we can catch all exceptions occurred inside a try block. Even we can use a catch block with an Exception type parameter to catch all exceptions happened inside the try block since in C#, all exceptions are directly or indirectly inherited from the Exception class.

//C#: Exception Handling: Handling all exceptions

using System;
class HandledException
{
    public static void Main()
    {
        int x = 0;
        int intTemp = 0;
        try
        {
            intTemp = 100/x;
            Console.WriteLine("Not executed line");
        }
        catch
        {
            Console.WriteLine("oException" );
        }
        Console.WriteLine("Result is {0}", intTemp);
    }
}

The following program handles all exceptions with Exception object.

//C#: Exception Handling: Handling all exceptions

using System;
class HandledException
{
    public static void Main()
    {
        int x = 0;
        int intTemp = 0;
        try
        {
            intTemp = 100/x;
            Console.WriteLine("Not executed line");
        }
        catch(Exception e)
        {
            Console.WriteLine("oException" );
        }
        Console.WriteLine("Result is {0}", intTemp);
    }
} 

Example of Throwing an Exception

C# provides the facility to throw an exception programmatically. The 'throw' keyword is used for doing the same. The general form of throwing an exception is as follows:

throw exception_obj;

For example, the following statement throws an ArgumentException explicitly.

throw new ArgumentException("Exception");
//C#: Exception Handling:
using System;
class HandledException
{
    public static void Main()
    {
        try
        {
            throw new DivideByZeroException("Invalid Division");
        }
        catch(DivideByZeroException e)
        {
            Console.WriteLine("Exception" );
        }
        Console.WriteLine("Final Statement that is executed");
    }
}  

Standard Exceptions

Exception are categorised into two types:

  1. exceptions generated by an executing program
  2. exceptions generated by the common language runtime.

As explained in the earlier section, System.Exception is the base class for all exceptions in C#. Several exception classes inherit from base class including ApplicationException and SystemException. These two classes form the basis for most of the runtime exceptions. Other exceptions are derived directly from System.Exception include IOException, WebException, etc.

The common language runtime throws SystemException. The ApplicationException is thrown by a user program rather than the runtime. The SystemException includes the ExecutionEngineException, StackOverFlowException, etc. It is generally not recommended to catch SystemExceptions, also it is not good programming practice to throw SystemExceptions in applications. Following are few of the examples of the above stated exception.

System.OutOfMemoryException
System.NullReferenceException
Syste.InvalidCastException
Syste.ArrayTypeMismatchException
System.IndexOutOfRangeException
System.ArithmeticException
System.DevideByZeroException
System.OverFlowException 

User-defined Exceptions

C# allows to create user defined exception class. This class should be derived from Exception base class. So the user-defined exception classes must inherit from either Exception class or one of its standard derived classes.

//C#: Exception Handling: User defined exceptions

using System;
class UserDefinedException : Exception
{
    public MyException(string str)
    {
        Console.WriteLine("User defined exception");
    }
}

class HandledException
{
    public static void Main()
    {
        try
        {
            throw new UserDefinedException ("New User Defined Exception");
        }    
        catch(Exception e)
        {
            Console.WriteLine("Exception caught here" + e.ToString());
        }
        Console.WriteLine("Final Statement that is executed ");
    }
} 

General Guidelines for Exception Handling

MS has given specific guidelines for exception handling that can be found at this link.

History

  • 11th February, 2021: Initial version

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here