Writing Custom Exceptions

Source Code: Download

This is the first post on my goal of writing 3 substantial posts by the end of the year. I decided to write this post on exception handling more specifically writing a Custom Exception. Why would we want to have custom exceptions.

The first reason to create an exception is because the exception you want does not exist. If there is not an exception in the system the has the functionality you are looking for then you need to create one. This gives you the ability add custom data to your exceptions. Now you can pass this data, in the exception, to your logging/handling mechanism.

The second reason would wrap system exception to provide more data. Like above you can add data to your exception and include the system exception as an inner exception.

One thing to keep in mind while working with exceptions is the overhead involved with exception handling. You should only throw and or catch exceptions when you are able to recover from them gracefully and or want to log them. This brings us to another point about exception handling, catch and work with the most specific exception you can. For instance catching a FileNotFoundException instead of a ApplicationException may make more sense. This is where you custom exceptions can come in handy.

How Do We Create One

When creating custom exceptions I like to put them in their own project. That way I can add a reference to all my other projects (UI, DAL, BLL) and have a common exception framework throughout.

Step1: Create a class that inherits from Exception. This class should be Serializable :

   1: [Serializable]

   2: public class EndOfTheWorldException : Exception

Step 2: Create some variables to hold your custom data.

Step 3: Create constructors to handle the different scenarios:

   1: public EndOfTheWorldException()

   2:    : base()

   3: {

   4:    base.HResult = HRESULT;

   5: }

   6:  

   7: public EndOfTheWorldException(string message)

   8:    : base(message)

   9: {

  10:    base.HResult = HRESULT;

  11: }

  12:  

  13: public EndOfTheWorldException(Person person)

  14:    : base()

  15: {

  16:    base.HResult = HRESULT;

  17:    _person = person;

  18: }

  19:  

  20: public EndOfTheWorldException(string message, Exception innerException)

  21:    : base(message, innerException)

  22: {

  23:    base.HResult = HRESULT;

  24: }

Step 4: Override the ToString method to display custom data and inner exception data:

   1: public override string ToString()

   2: {

   3:     StringBuilder sb = new StringBuilder();

   4:     sb.Append(Environment.NewLine);

   5:     sb.Append(Environment.NewLine);

   6:     sb.AppendFormat("{0}: {1}", CLASS_NAME, this.Message);

   7:     sb.Append(Environment.NewLine);

   8:     sb.Append(Environment.NewLine);

   9:     sb.AppendFormat(" Person: '{0}' ", _person.ToString());

  10:     sb.Append(Environment.NewLine);

  11:     sb.Append(Environment.NewLine);

  12:     sb.AppendFormat(" IP Address: '{0}' ", _ipAddress);

  13:     sb.Append(Environment.NewLine);

  14:     sb.Append(Environment.NewLine);

  15:  

  16:     if (this.InnerException != null)

  17:     {

  18:         sb.AppendFormat(" ---> {0} <---", base.InnerException.ToString());

  19:     }

  20:  

  21:     if (this.StackTrace != null)

  22:     {

  23:         sb.Append(Environment.NewLine);

  24:         sb.Append(base.StackTrace);

  25:     }

  26:  

  27:     return sb.ToString();

  28: }        

Now you have a basic custom exception. You can add as much functionality as needed such as adding a HelpLink. Since you are inheriting from Exceptions the possibilities are endless.

How Do We Use Our Exception

Using your exception is just as easy as adding a reference to your project and off you go. I have created a DTO project with a person object. In my exception I want to capture the person object and the IP address of the machine.

Here is an example of using my custom exception. This example shows catching a general exception (not good practice) and log the exception to the event viewer. It also writes the exception out to the screen:

   1: //Too General - catches all exceptions

   2: try

   3: {

   4:     throw new EndOfTheWorldException("This is the end of the world", p, ipAd);

   5: }

   6: catch (Exception ex)

   7: {                

   8:     EventLog.WriteEntry("TestException", ex.ToString(), EventLogEntryType.Error);

   9:     Console.WriteLine(ex.ToString());

  10: }

Here is what the exception looks like in the Event Viewer. Notice the custom data (IP Address and Person):

Here is what the code would look like when wrapping a system exception:

   1: //Wraps System Exceptions

   2: try

   3: {

   4:     throw new ApplicationException("This will be the inner exception");

   5: }

   6: catch (ApplicationException ex)

   7: {

   8:     EndOfTheWorldException e = new EndOfTheWorldException("This is the end of the world", p, ipAd, ex);

   9:     EventLog.WriteEntry("TestException", e.ToString(), EventLogEntryType.Error);

  10:     Console.WriteLine(e.ToString());

  11: }

and now in the Event Viewer (notice the inner exception):

Summary

You now have the tools you need to create and use custom exceptions while maintaining the rich functionality in the native Exception Framework.

You can get the source code to my demo code here.

This entry was posted in .NET, C#, Exception Handling. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s