I had one of those great “I told you so” moments with a consulting customer today. About a month ago, I recommended using the Exception Management Application Block (EMAB)for publishing their exceptions because of the ease of use and extensibility it offered. If you are unfamiliar, the EMAB lets you publish exception information in a catch block to any number of publishers with a single line of code:
catch (Exception ex)
Through the config file, you can then wire up zero to many publishers such as the built in Windows Event Log publisher, an XML file, a database, email, and so on. You can modify where the exception information gets published anytime without changing anything but the config file. You can create your own custom publishers and plug them in very easily as well.
So what I had proposed was to create a custom publisher that would log any exceptions to their existing application event log, whichis just a SQL Server table that their monitor application accesses, with all the details that come along with the exception (message, stack trace, target, user, date time, etc.). The customer balked because they were intimidated by the block andthought it was too complex for their needs. “We never need to publish anywhere except our event log, and we already have code that does that”. Uh-huh, sure. Never huh?
Today the customer stumbled down a dark and windy road of synchronization nightmares due most likely to a shared data object class that was being hammered on by multiple threads and didn’t have complete and safe synchronized access to its members. “Everything worked great in debug mode, but when we run in release mode, it blows up right away with a null reference exception.”
Oh great, I love these. Where is it blowing up exactly, I asked? “We don’t know, we didn’t have room in the database fields for the full stack trace, so we just left that out.” Mmm. OK. Brute force time. Lets insert a trace statement in the exception handlerto dump the context so we can see what is going on. Oh goody, just inserting trace statements in the method where it is occuring makes the problem go away. Surely no race condition here.
Then the customer ponders – “how can we get more information out about the exception if the exception goes away when we add more code to dump it?” Exactly. Wouldn’t it be nice to just wire up a different publisher right now that can dump the full exception – type, message, stack trace, etc. – to an XML file or somewhere else for analysis without having to modify the code. Why yes it would.
Extensibility is your friend, especially when someone else (thank you Microsoft) has implemented it for you. I am absolutely against speculative design. But you also have to be realistic about things that might need to change after you ship and make allowances for them. If there are things you can use like the Exception Management Application Block, or any of the other applications blocks that give you an extensible design that just requires a little extra up front complexity to integrate, think seriously about what it might buy you down the road. We probably could have tracked down the exact cause of the problem today quickly if we just had complete information about the exception. And that information could have been easily obtained, even in release mode, without changing a line of code, if they had used the EMAB instead of a home grown, non-extensible solution.