Exceptions and Preserving Exception Types

An interesting thing happened to me today, while working on an enhancement for the application my company supports.

I was tasked with ensuring validation worked on collection of objects, exactly the same as if it were a single object being modified. Normally a straightforward thing, but due to how the application does its 'thing' and how it handles different types of exceptions, a little bit of tweaking was necessary, and during the course of this tweaking I noticed a very strange behaviour with my error handling...

We handle/catch exceptions at almost every layer of our application (as opposed to throwing it once and everything magically bubbling up) due to some of the complex processing required when we hit an error. So i was very confused that during the course of debugging my changes today, Exception blocks were not 'catching' when being bubbled up. Crazy!

I had the following code in the Click Event Handler of my Save button.

try
{
SaveObjects();
}
catch (Exception ex)
{
lblMessage.Text = ex.Message;
}

What was happening was, the WarningException being thrown from the update of the singular object wasn't bubbling up as I thought it would into the UI layer. It was completely skipping the WarningException block and being bubbled up into the generic Exception handler in the btnSave_Click event handler.

Took a little bit of investigation, but as it turned out this was being caused by an evil little middle-man between the singular object Update method and the btnSave_Click event... the Update method in my collection object!\

I had the following code in the update method of my collection object.

try
{

// Main processing //
foreach (Object r in this.InnerList)
{
r.Update();
}
}
catch (BusinessRuleException e)
{

throw new BusinessRuleException(e.Message);

}
catch (Exception e2)
{

throw new Exception(e2.Message);
}

You might have noticed that in the exception blocks in the collection object DONT handle a warning exception! So what was happening was, the singular object was throwing a WarningException, however the collection object exception blocks were catching it as a generic Exception, therefore losing the Exception type by the time it was getting to the UI layer it had lost its custom type!

Moral of the story is: when handling exceptions across layers, ALWAYS ensure you handle them consistently across all layers! Or you'll start losing information!

I realise this isn't exactly groundbreaking stuff, but i thought it was interesting and worth sharing :)