Publish Exception Info Anywhere

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

Brian Noyes

October 30, 2009

9 Min Read
ITPro Today logo in a gray background | ITPro Today

DataStream

LANGUAGES: C#

ASP.NET VERSIONS: 1.0 | 1.1

 

PublishException Info Anywhere

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

 

By BrianNoyes

 

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

 

Thechallenge lies in what to do within your exception handling catch blocks. Youmay have catch blocks in any number of places in your application, hopefullyincluding top-level catch blocks that prevent unhandled exceptions from leakingout of your application. Typically, the first thing you want to do is capturethat exception information and stuff it somewhere for debugging or offlinediagnostic purposes. That somewhere could be any number of places, including aflat file, XML file, database, or generating notifications through e-mail orinstant messaging. Unfortunately, attempting to write out exception informationto any of those places can result in an exception as well, leading to nestedtry-catch blocks that start to litter up your application in a hurry.

 

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

 

You canread 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 developmentmachine. This will add some VS .NET projects and documentation to your machineand 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 .NETversion so you can then reference the resulting class library assembly fromother application projects that you build.

 

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

To useEMAB from application code requires a single line of code in any of yourapplication exception catch blocks:

 

catch(Exception ex)

{

  ExceptionManager.Publish(ex);

}

 

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

 

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

 


Figure 1. When you publish an exception withEMAB, the ExceptionManager checks in your configuration file to decide to whichpublishers to send the information.

 

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

 

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

 

Configure the Block

Theapplication configuration file entries required are pretty straightforward. Thefirst thing required is a section entry in the elementthat identifies the section handler for EMAB itself. You then need to add thatsection, and add elements to it identifying all of thepublishers that you want invoked when an exception is published. You can also enableand disable exception publishing simply by changing a mode attribute in theexception 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"/>    Figure2. Yourapplication configuration file entries provide the glue that ties theExceptionManager to the appropriate publishers for outputting exceptioninformation. Note that the type attribute of the section element in theconfigSections element has been wrapped; you will need to put that section allon one line if you want to cut and paste this text. Attributes in XML cannothave a line break in them.   Theattributes required for a particular publisher element depend on theimplementation of that publisher. Each publisher can have any number of customattributes that identify information it needs to know in order to publishexception info, and the publisher will be passed that information whenever anexception is published. For example, the first publisher shown in Figure 2publishes to a custom database table, so the publisher info needs to containthe server name and database name where the table is located. The secondpublisher in Figure 2 publishes to an XML file, so it needs to know the path tothe 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 eventlog. The block comes with a sample application that includes a publisher forXML files and for sending an e-mail. They are fairly limited though, so thedownload code for this article includes three additional publishers in aproject called EMABPublishers that should be a little more useful to you inyour production applications. The ExceptionXmlFilePublisher writes outexceptions to a specified XML file, appending each new exception to thedocument as a running commentary. The DBExceptionLogPublisher will publish theexception information to a custom DB table that can be created with the SQL scriptincluded in the download code. Finally, the SqlExceptionPublisher is aspecialized publisher that just handles SqlExceptions and outputs morespecialized information about the SqlErrors collection that is contained inthose exceptions. See my article GainInsight Into SQL Errors for more information on the SqlErrors collection.   Tocreate custom publishers, you just need to create a class that implements oneof two interfaces defined in EMAB: IExceptionPublisher orIExceptionXmlPublisher. If you implement IExceptionPublisher, yourimplementation of the Publish method will just be handed the raw Exceptionobject that was published from the application's call toExceptionManager.Publish and it will be up to your publisher to strip out theproperties and inner exceptions it cares about and publish them appropriately.If you implement the IExceptionXmlPublisher, your publisher will be passed anXmlDocument object that already has all of the properties and nested innerexceptions serialized into it, so that can simply be written out if the defaultschema and XML format are acceptable to you.   Anotherthing to be aware of when using EMAB is that it is recommended that you deriveany custom application exception types from EMAB base classBaseApplicationException, instead of the normal .NET ApplicationException baseclass recommended in the .NET design guidelines. This is because EMABBaseApplicationException class will also publish out some valuable additionalcontext information any time an exception is raised, including the machinename, 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 ofadditional information values that you can stuff anything into. Thisinformation will get automatically collected and published along with yourcustom exception, which can be really handy in many scenarios.   Final Words of Wisdom If youfind yourself thinking that you don't really need EMAB because you already havea way of getting your exception information published, and you don't think youneed the flexibility of changing where it goes, think again. I have run intothe situation on more than one occasion where an application was designed withcustom code to output their exception information and the designers thoughtthey would never have a need to put it out somewhere else. But things go wrongsometimes, and when they do, options are a good thing to have. Being able tomake your application spit out full details on exceptions to some location andform never conceived of when the application was designed without changing aline of application code is a powerful option. It also means that the code inyour application related to exceptions is reduced, which eases your maintenanceburden significantly. Any publishing code you write also becomes easilyreusable on other applications - yet another plus.   Thebottom line: I highly suggest you check out EMAB and consider including it inyour current and future applications. The benefits of using it are subtle untilyou use it a bit, and then you start to realize you have been doing things thehard way.   Thefiles accompanying this article are available for download.   BrianNoyes is asoftware architect with IDesign, Inc. (http://www.idesign.net),a .NET focused architecture and design consulting firm. Brian specializes indesigning and building data-driven distributed Windows and Web applications. Hehas over 12 years experience in programming, engineering, and projectmanagement, and is a contributing editor and writer for asp.netPRO and otherpublications. Contact him at mailto:[email protected].        

Sign up for the ITPro Today newsletter
Stay on top of the IT universe with commentary, news analysis, how-to's, and tips delivered to your inbox daily.

You May Also Like