Working with Exceptions using C#
page 1 of 1
Published: 03 Apr 2006
Unedited - Community Contributed
Abstract
Exceptions are errors that occur at run time. In this article, Joydip focuses on a generic approach towards handling exceptions.
by Joydip Kanjilal
Feedback
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 8957/ 11

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.



User Comments

Title: The Best article found so far   
Name: PPCUBAN
Date: 2006-06-15 11:09:49 PM
Comment:
Very Good. I had my doubts about the Excetion. Now I feel more secure about this topic.
Title: Caveat   
Name: Lorad
Date: 2006-04-11 12:57:15 PM
Comment:
While this a decent example of how to create a custom exception class, I don't think it is a good example of when to USE that custom class.

Custom exceptions should be something you use when your method fails and you want to report an exceptional case like you pointed out. It should not be used to wrapper up every exception. You lost the stack trace information without delving into the custom exception.

So unless all down streams catch CustomException and throw; them and not wrapper them up you will have some unknown depth of CustomException. So you would always have a minimum of catch statements and that is for CustomException and Exception, wrappering Exception.

I would argue you should never catch (Exception ex) unless you are just using it to log some information then do a throw; (NOT a throw ex; - as once again this would reset the call stack). Exceptions should only be caught if you can recover from them. (or log them for post mortum)
Title: Exception   
Name: Nivedita
Date: 2006-04-08 2:05:05 AM
Comment:
Explain with a simple example step by step.
Moreover I want to understand the concept of paymemt gateways.how it works and is being used in the forms
Title: Excellant   
Name: Seema
Date: 2006-04-05 11:09:19 AM
Comment:
This is a wonderful article. Fastastic work!!! Thanks

Product Spotlight
Product Spotlight 





Community Advice: ASP | SQL | XML | Regular Expressions | Windows


©Copyright 1998-2024 ASPAlliance.com  |  Page Processed at 2024-03-28 7:50:40 PM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search