Skip navigation

Publish Exception Info Anywhere

Publish information about exceptions to a variety of locations with a single line ofcode using the Exception Management Application Block.

DataStream

LANGUAGES: C#

ASP.NET VERSIONS: 1.0 | 1.1

 

Publish Exception Info Anywhere

Publish information about exceptions to a variety of locations with a single line of code using the Exception Management Application Block.

 

By Brian Noyes

 

.NET Exceptions provide a great way of managing errors within an application. Exceptions can get thrown anywhere in an application, either from doing something wrong with the .NET Framework or a third-party library, or because something unexpected happened in your application and you decided to throw an appropriate exception. Exceptions will bubble up the stack until a matching exception handler (catch block) is found, freeing you from having to pass error context information up the stack yourself - as was often done in the past using DWORD error codes or booleans as the return values of functions.

 

The challenge lies in what to do within your exception handling catch blocks. You may have catch blocks in any number of places in your application, hopefully including top-level catch blocks that prevent unhandled exceptions from leaking out of your application. Typically, the first thing you want to do is capture that exception information and stuff it somewhere for debugging or offline diagnostic purposes. That somewhere could be any number of places, including a flat file, XML file, database, or generating notifications through e-mail or instant messaging. Unfortunately, attempting to write out exception information to any of those places can result in an exception as well, leading to nested try-catch blocks that start to litter up your application in a hurry.

 

This process of publishing the exception information is rarely a core function of your application, but more of an ancillary infrastructure requirement that is necessary to ensure that when problems occur, you can identify, isolate, and fix them. The rest of your catch block may perform application-specific logic, such as aborting transactions, performing compensating transactions, calling clean up routines, etc. There is no good way to abstract out application-specific logic like that in a reusable, generic way. But the process of publishing captured exception information can be handled in a generic and extensible manner, and that is precisely what the Exception Management Application Block (EMAB) provides.

 

You can read all the details about EMAB and download it from MSDN (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/emab-rm.asp). What you will need to do is download and install EMAB on your development machine. This will add some VS .NET projects and documentation to your machine and will also install a Windows Event Log that EMAB will publish to by default. Once it is on your machine, you'll want to compile either the C# or VB .NET version so you can then reference the resulting class library assembly from other application projects that you build.

 

One of the Most Useful Lines of Code You Will Ever Write

To use EMAB from application code requires a single line of code in any of your application exception catch blocks:

 

catch (Exception ex)

{

  ExceptionManager.Publish(ex);

}

 

For this to compile, you'll need to set a reference to the EMAB class library, which you compile from the code installed with EMAB. Once you have added this line of code to your catch blocks, any time an exception gets caught by that block, it will be published by EMAB to whichever publishers you have configured for the application.

 

OK, so what is a publisher and how do you configure it? Figure 1 depicts the basic flow of the way the ExceptionManager works. First off, you need to have a little information in your application configuration file to identify the configuration section that affects the operation of EMAB. When you call Publish on the ExceptionManager from your application code, it will check in that configuration section for information on where to publish.

 


Figure 1. When you publish an exception with EMAB, the ExceptionManager checks in your configuration file to decide to which publishers to send the information.

 

So the first thing that is great about EMAB is the fact that it requires so little code in your application. If something goes wrong in the publishing process, EMAB will attempt to output exception information about whatever went wrong to its default publisher, which targets the Windows application event log. If that fails as well, it will just quietly ignore the error. So you don't have to worry about nesting try-catch blocks in your app code to cover any problems during the publishing process.

 

The other thing that is awesome about EMAB is the extensible design that allows you to plug in any number of publishers, including ones that you write, at run time. Using this capability, you might deploy your application to just write to a database event log of your own. But then, if you are troubleshooting some database problems, you could plug in a new XML file publisher without having to change any application code and have the exceptions dumped to an XML file that is easy to reach out and inspect remotely.

 

Configure the Block

The application configuration file entries required are pretty straightforward. The first thing required is a section entry in the element that identifies the section handler for EMAB itself. You then need to add that section, and add elements to it identifying all of the publishers that you want invoked when an exception is published. You can also enable and disable exception publishing simply by changing a mode attribute in the exception management element (see Figure 2).

 

  

    

    type="Microsoft.ApplicationBlocks.

    ExceptionManagement.ExceptionManagerSectionHandler,

    Microsoft.ApplicationBlocks.ExceptionManagement" />

  

  

    

    type="EMABPublishers.DBExceptionLogPublisher"

    exceptionFormat="xml"

    serverName="localhost" dbName="ExceptionLog"/>

    

    type="EMABPublishers.ExceptionXmlFilePublisher"

    exceptionFormat="xml"

    xmlFilePath="C:\CustomExceptions.xml"/>

  

Figure 2. Your application configuration file entries provide the glue that ties the ExceptionManager to the appropriate publishers for outputting exception information. Note that the type attribute of the section element in the configSections element has been wrapped; you will need to put that section all on one line if you want to cut and paste this text. Attributes in XML cannot have a line break in them.

 

The attributes required for a particular publisher element depend on the implementation of that publisher. Each publisher can have any number of custom attributes that identify information it needs to know in order to publish exception info, and the publisher will be passed that information whenever an exception is published. For example, the first publisher shown in Figure 2 publishes to a custom database table, so the publisher info needs to contain the server name and database name where the table is located. The second publisher in Figure 2 publishes to an XML file, so it needs to know the path to the XML file to which it should write.

 

Pick Your Publishing Target

The only "built-in" publisher in EMAB is the one that publishes to an application event log. The block comes with a sample application that includes a publisher for XML files and for sending an e-mail. They are fairly limited though, so the download code for this article includes three additional publishers in a project called EMABPublishers that should be a little more useful to you in your production applications. The ExceptionXmlFilePublisher writes out exceptions to a specified XML file, appending each new exception to the document as a running commentary. The DBExceptionLogPublisher will publish the exception information to a custom DB table that can be created with the SQL script included in the download code. Finally, the SqlExceptionPublisher is a specialized publisher that just handles SqlExceptions and outputs more specialized information about the SqlErrors collection that is contained in those exceptions. See my article Gain Insight Into SQL Errors for more information on the SqlErrors collection.

 

To create custom publishers, you just need to create a class that implements one of two interfaces defined in EMAB: IExceptionPublisher or IExceptionXmlPublisher. If you implement IExceptionPublisher, your implementation of the Publish method will just be handed the raw Exception object that was published from the application's call to ExceptionManager.Publish and it will be up to your publisher to strip out the properties and inner exceptions it cares about and publish them appropriately. If you implement the IExceptionXmlPublisher, your publisher will be passed an XmlDocument object that already has all of the properties and nested inner exceptions serialized into it, so that can simply be written out if the default schema and XML format are acceptable to you.

 

Another thing to be aware of when using EMAB is that it is recommended that you derive any custom application exception types from EMAB base class BaseApplicationException, instead of the normal .NET ApplicationException base class recommended in the .NET design guidelines. This is because EMAB BaseApplicationException class will also publish out some valuable additional context information any time an exception is raised, including the machine name, the date and time of the exception, the thread and AppDomain identity, the identity of the account that the app is running under, and a collection of additional information values that you can stuff anything into. This information will get automatically collected and published along with your custom exception, which can be really handy in many scenarios.

 

Final Words of Wisdom

If you find yourself thinking that you don't really need EMAB because you already have a way of getting your exception information published, and you don't think you need the flexibility of changing where it goes, think again. I have run into the situation on more than one occasion where an application was designed with custom code to output their exception information and the designers thought they would never have a need to put it out somewhere else. But things go wrong sometimes, and when they do, options are a good thing to have. Being able to make your application spit out full details on exceptions to some location and form never conceived of when the application was designed without changing a line of application code is a powerful option. It also means that the code in your application related to exceptions is reduced, which eases your maintenance burden significantly. Any publishing code you write also becomes easily reusable on other applications - yet another plus.

 

The bottom line: I highly suggest you check out EMAB and consider including it in your current and future applications. The benefits of using it are subtle until you use it a bit, and then you start to realize you have been doing things the hard way.

 

The files accompanying this article are available for download.

 

Brian Noyes is a software architect with IDesign, Inc. (http://www.idesign.net), a .NET focused architecture and design consulting firm. Brian specializes in designing and building data-driven distributed Windows and Web applications. He has over 12 years experience in programming, engineering, and project management, and is a contributing editor and writer for asp.netPRO and other publications. Contact him at mailto:[email protected].

 

 

 

 

Hide comments

Comments

  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
Publish