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
{
}
catch(Type x)
{
}
finally
{
}
try
-catch
-finally
block in ASP.NET:
<Script runat=server>
Public Page_Load(sender As Object, e As EventArgs)
{
try
{
}
catch(Type x)
{
}
finally
{
}
}
</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)
{
}
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)
{
}
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:
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. On
: The detailed ASP.NET error page is never shown, even to local users. If a custom error page is available, it is displayed. 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.
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
{
}
catch(Type x)
{
}
finally
{
}
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.
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.
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#.
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.
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.
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.
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");
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:
- exceptions generated by an executing program
- 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.
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