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

A Reusable, Flexible Error Reporting Framework

0.00/5 (No votes)
28 Apr 2004 1  
Using configuration classes and simple implementation, this library allows your applications a flexible method of reporting errors that happen. Included is a Windows XP-like WinForms UI that allows users the ability of opting for error reporting in WinForms applications.

Introduction

Error handling is one of the more difficult tasks any developer or development team must implement. Teams face all sorts of challenges on how to handle exceptions within applications. Oftentimes, you end up "re-creating the wheel" for every application you design; since many believe that the application's provisions dictate the exception-handling methodology, you end up needing to recreate exception handling for each application you develop.

Microsoft has provided you with a large method of exception management with their Exception Application Block, but for many application scenarios, this block may be too large. Though it provides many degrees of flexibility, it can be cumbersome to set up and configure, and in a lot of cases, even larger than the application you're developing!

This article will present a far simpler approach, and provide you with a flexible library you can use to handle your own exceptions. The ErrorTrapper library is completely self-contained within a single .NET assembly, and is relatively flexible to use via specifying information in your App.config or Web.config file. First, the design of the ErrorTrapper will be discussed in short detail. Then, a sample scenario will be presented using WinForms technology which will demonstrate a relatively basic implementation of the ErrorTrapper's usefulness.

First things first - the IErrorReporter interface

The main component of the ErrorTrapper library - the part which will yield flexibility in the design of the model itself - is the IErrorTrapper. Below, you can see the C# code which provides this interface's structure:

public interface IErrorReporter
{
    bool ReportError(Exception exception);
}

Classes which implement this interface need only contain implementation for the single method ReportError(). Your own classes can provide whatever implementation you need for the application, using the ErrorTrapper library. In a moment, we'll take a look at using late binding and the Activator.CreateInstance() method to create instances of types which can implement this functionality.

The code download provided with this article contains a simple WinForms application which utilizes the ErrorTrapper library. This implementation simply writes the ToString() equivalent of the handled exception to a file on disk. Below, you can see the code for this class and get an idea of how flexible the ErrorTrapper library can be in your own application development cycles:

public class CustomErrorTrapperExample : IErrorReporter
 {
  public bool ReportError(Exception exception)
  {
   try
   {
    string filename = @"C:\ExceptionLog.txt";
    FileMode fm = FileMode.Append;

    if(!File.Exists(filename))
    {
     fm = FileMode.Create;
    }

    StringBuilder sb = new StringBuilder();
    FileStream fs = new FileStream(filename,fm);
    sb.Append(DateTime.Now.ToString());
    sb.Append(Environment.NewLine);
    sb.Append("---------------------------------------------------------");
    sb.Append(Environment.NewLine);
    sb.Append(exception.ToString());
    sb.Append(Environment.NewLine);
    sb.Append("---------------------------------------------------------");
    sb.Append(Environment.NewLine);
    string s = sb.ToString();
    Byte[] byt = Encoding.ASCII.GetBytes(s);
    fs.Write(byt,0,byt.Length);
    fs.Close();
    return true;
   }
   catch
   {
    return false;
   }
  }

Though this is a relatively simple example, it demonstrates how you can, in your own application paradigm, write custom implementations that the ErrorTrapper library will execute whenever applications "explode".

So how can I make it flexible?

The answer to this question is relatively simple. Using a custom configuration section in your app.config or web.config file, you'll provide some information that "drives" certain aspects of the ErrorTrapper library. As you'll see in a moment, there is a user interface aspect to the ErrorTrapper. For now, let's save that discussion and take a look at the configuration code that provides information to the library at runtime.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
 <configSections>
  <section name="ErrorTrapper" 
   type="System.Configuration.NameValueSectionHandler" />
 </configSections>
 <ErrorTrapper>
  <add key="exceptionHandlerType" 
       value="ClientApplication.CustomErrorTrapperExample,
        ClientApplication"/>
  <add key="showUI" value="true"/>
  <add key="uiLabel" value="Something Exploded!"/>
  <add key="uiIntro" 
       value="We're sorry, but something has happened. 
        Would you like to report this explosion?"/>
 </ErrorTrapper>
</configuration>

As you can see from this configuration section, we're going to use a relatively simple paradigm for configuring the ErrorTrapper library. By using the NameValueSectionHandler configuration class, we'll provide four properties that the ErrorTrapper will need to use at runtime:

  • exceptionHandlerType (string)
  • showUI (bool)
  • uiLabel (string)
  • uiIntro (string)

The first of these properties, exceptionHandlerType, will be the name of a Type that the ErrorTrapper will create at run-time to handle exceptions. One caveat is important to note here - the Type provided in this area must implement the IErrorReporter interface! If it does not, an exception will be thrown at runtime (makes sense if you think about it!). The class we discussed earlier with the simple implementation - CustomErrorTrapperExample - has been provided in this example.

Now - the WinForms interface!

Microsoft Windows and some of the supporting applications provide us with an awesome feature - the ability to send errors as they occur to a Microsoft Web Service which tallies up the exceptions that happen in their applications. You've seen the dialog that pops up from time to time when certain programs "explode", providing you the option of reporting the error to Microsoft.

Well, the ErrorTrapper library provides something very similar for your WinForms applications - a user interface that displays the exception's information, with a "Send" and "Don't Send" button your users can use as they wish. The dialog displayed by this implementation is below:

The ErrorTrapper WinForms UI

Now that you've got a reference, we'll continue the examination of the final three configuration elements. The first of these, a Boolean property called showUI, can be used to specify whether the UI is displayed or not. Think about it this way - if you want to use the ErrorTrapper in a WebForms application, it wouldn't be a good idea to display this UI. If this value is set to true, the user has the option of submitting the exception to your custom IErrorReporter implementation. If the value is set to false, your implementation simply executes.

Next is the uiLabel property. In the example screenshot, this value has been set to the string "Something Exploded!". Simply, this element/property defines the dialog's Text property, and is displayed in the title bar of the WinForm when it is shown.

Finally, the uiIntro property. Pretty simply, this is the text which is displayed to the user above the buttons. As you can see from this example, you can customize not only the functionality that happens when exceptions are handled by the ErrorTrapper library - you can even customize the dialog that's displayed to users when exceptions are handled in a WinForms application! Total flexibility!

Finally, Using the ErrorTrapper

The last piece of code we'll take a look at is from the sample download. This WinForms user interface provides two buttons that fire - or cause - simple exceptions. At the beginning of the application's execution, we'll simply handle the ThreadException event, and within the event handler, send the exception that is fired into the ErrorTrapper's execution cycle. The code for this is below:

static void Main() 
  {
   Application.ThreadException += new 
     System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
   Application.Run(new Form1());
  }

  private static void Application_ThreadException(object sender, 
     System.Threading.ThreadExceptionEventArgs e)
  {
   ErrorHandler.HandleError(e.Exception);
  }

  private void btnSimpleError_Click(object sender, System.EventArgs e)
  {
   throw new Exception("This is a simple error");
  }

  private void btnDbFailure_Click(object sender, System.EventArgs e)
  {
   SqlConnection cn = new SqlConnection("this will break");
   cn.Open();
  }

And that's about it! Here you have a simple, flexible, and totally customizable exception management tool, complete with a Windows XP-like user interface that can be displayed to your users should you want to provide them the option of reporting or not reporting exceptions as they occur!

Happy coding!

Note - this assembly has already been strong-named and documented for you. So feel free to drop it into your GAC and use it wherever you need!

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