This article discusses the basics of exceptions and
implementation of a custom exception class that would enable us to provide a
generic approach towards exception handling.
What is an Exception?
An exception is an error that occurs at runtime. If it is
not handled properly, it terminates the normal flow of the program.
Try, Catch and Finally – an insight
Exceptions are handled using the try, catch and finally
blocks. The try block contains code that causes an exception. The exceptions
that are raised in the try block are caught in one or more catch blocks. The
finally block contains any necessary cleanup code. It should be noted that a
try block should contain one or more catch blocks or at least a finally block.
Only one of the catch blocks is executed.
A finally block is executed whether or not an exception
occurs. Hence, it is particularly useful to be used for cleanup operations. Let
us consider that we have opened a database connection in a try block. If an
exception occurs, it is caught in the catch block just after the try block as
shown in the code snippet below:
Listing 1: Try, catch and finally --- a final look
SqlConnection con;
try
{
/*Usual code to instantiate the con object andprovide the connection string. */
con.Open();
}
catch (Exception ex)
{
//Some exception handling code
}
finally
{
con.Close();
}
If we do not use a finally block and close the connection
after the catch block, the connection object might not be closed always. This
is because when an exception occurs, the control enters the respective catch
block after which it terminates. Code that follows the catch block is never
executed. Hence, a finally block is mandatory under such circumstances. So, the
moral is, write all your cleanup code in the finally block only.
Implementing a Custom Exception class
In order to implement a Custom Exception class we have to
derive our Custom Exception class from the class called ApplicationException.
This is shown in the listing below:
Listing 2: Designing a Custom Exception class
using System;
public class CustomException:ApplicationException{
}
We need to provide custom error messages to our custom
exception class. We take an enum for the type of errors that might occur. This
enum is as given below:
Listing 3: The ErrorType enumerator
public enum ErrorType
{
DatabaseError, LogicalError, ArithmeticError,Other, Base
}
There may be more and more types of errors for which the
readers are advised to put them in the enum given above. We store custom error
messages corresponding to the error types given above in a hash table object.
This is shown below:
Listing 4: The ErrorMessage class
internal sealed class ErrorMessage
{
private Hashtable errorList = new Hashtable();
public ErrorMessage()
{
errorList.Add(ErrorType.Database, "Failedto connect to the
database table. ");
errorList.Add(ErrorType.Remoting, "Anerror connecting to the
remote object has occured. ");
errorList.Add(ErrorType.Arithmetic, "Anattempt to divide by zero.
");
errorList.Add(ErrorType.Other, "Anunknown error has occured. ");
}
public string this[ErrorType key]
{
get
{
return errorList[key].ToString();
}
}
}
The class is internal and sealed. It stores in its
constructor the custom error messages that correspond to the error types of the
ErrorType enum. The readers can store more messages simply by making a call to
the Add method of the hash table object and passing the error type as key and
the error message as value. Notice that we have an indexer implemented in this
class. The indexer accepts the error type and returns the corresponding error
message.
We have the following types of errors in the enum Errortype:
·
Database
·
Remoting
·
Arithmetic
·
Other
·
Base
Here, Base indicates that we will not show any custom error
message. Rather, the error message of the originating Exception object would be
displayed. The “Other” error type indicates an unexpected error that might
occur when the program is executed. More and more error types can be added, but
the corresponding error message should be stored in the hash table. Notice that
we do not have any error message stored in the hash table object errorList for
the “Base” error type. This is because we display the error message of the
originating exception object when the Base error type is specified.
The following program is a complete listing of the concepts
applied so far.
Listing 5: The complete implementation
using System;
using System.Collections;
namespace UtilityLibrary
{
public enum ErrorType
{
Database, Remoting, Arithmetic, Other, Base
}
internal sealed class ErrorMessage
{
private Hashtable errorList = newHashtable();
public ErrorMessage()
{
errorList.Add(ErrorType.Database,"Failed to connect to the
database table. ");
errorList.Add(ErrorType.Remoting, "Anerror connecting to the
remote object has occured. ");
errorList.Add(ErrorType.Arithmetic,"An attempt to divide by
zero.");
errorList.Add(ErrorType.Other, "Anunknown error has occurred.");
}
public string this[ErrorType key]
{
get
{
return errorList[key].ToString();
}
}
}
public sealed class CustomException:ApplicationException
{
private ErrorMessage errorMessage = newErrorMessage();
private Exception exception;
private ErrorType errorType;
public override string Message
{
get
{
if (errorType == ErrorType.Base)
return exception.Message.ToString();
returnerrorMessage[this.errorType].ToString();
}
}
public Exception ExceptionObject
{
get
{
return this.exception;
}
set
{
this.exception = value;
}
}
public ErrorType CustomErrorType
{
get
{
return this.errorType;
}
set
{
this.errorType = value;
}
}
public CustomException(){
}
public CustomException(Exception exception,ErrorType errorType)
{
this.exception = exception; this.errorType= errorType;
}
}
}
The CustomException class also contains properties to
get/set the Exception object and the ErrorType.
Let us now write a small program that uses the custom
exception class. Create a new project and add the UtilityLibrary.dll as a
reference to this project. Add a web form called CustomExceptionTest.aspx and
write the following code in its code behind. The complete listing of
CustomExceptionTest.aspx.cs is given below.
Listing 6: The CustomExceptionTest class
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using UtilityLibrary;
namespace Test
{
public class CustomExceptionTest:System.Web.UI.Page
{
private void Page_Load(object sender,System.EventArgs e)
{
try
{
Calculate();
}
catch (CustomException ce)
{
Response.Write(ce.Message);
}
}
override protected void OnInit(EventArgs e)
{
InitializeComponent();
base.OnInit(e);
}
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);
}
private void Calculate()
{
int p = 100;
int q = 0;
try
{
int r = p / q;
}
catch (Exception e)
{
throw new CustomException(e,ErrorType.Arithmetic);
}
}
}
}
The Calculate method re-throws the exception by creating an
object of the CustomException class and passing the Exception object and the
ErrorType as parameters. This method can also be written as follows:
Listing 7: The Calculate method revisited
private void Calulate()
{
int p = 100;
int q = 0;
try
{
int r = p / q;
}
catch (Exception e)
{
CustomException ce = new CustomException();
ce.CustomErrorType = ErrorType.Arithmetic;
ce.ExceptionObject = e;
throw ce;
}
}
In this case, we create the object of the CustomException
class first and then set the properties CustomErrorType and ExceptionObject to
their respective values. Then we throw the CustomException class object.
Suggested Readings
http://www.c-sharpcorner.com/Code/2005/May/CustomExceptionHandling.asp
http://msdn.microsoft.com/library/en-us/cpguide/html/cpconbestpracticesforhandlingexceptions.asp?frame=true
Conclusion
Exceptions should not be used frequently or as a means of
determining program flow, as they slow down the program execution. They should
only be used when required -- in exceptional cases.
In this article, I have examined how to implement a Custom Exception class in
C#. I welcome the readers to send in their comments by posting messages here.