Microsoft Exception Handling Block - Isn't it a perfect example for overengineering?

If you use exceptions for control flow, then you would want to stay away from policy-based exception handling.

But in the case of exceptions which you want to treat as non-recoverable (a background task failed, the socket was disconnected, the file was deleted, etc.), you may want to have configurable, policy-based exception handling.

For example, if you are developing an API, you may want to have every function in your API throw only the standard exceptions (ArgumentException, etc.), as well as your own library-specific exception in the case of an inner non-standard exception (e.g. a MyLibraryException). In this type of case, all that matters is that something did not work correctly. You are not picking apart the exception and figuring out what went wrong. You are simply acknowledging the fact that something went wrong, and that you are supposed to do something now.

That something should be configurable, because it doesn't really matter what you do. Display a Message Box to the user? Modal or non-modal? Log the exception? How do you want to log the exception? Call a logging web service? Append to a log file? Write to the Windows Event Log? Insert an entry into the database? Insert an entry into two databases? It doesn't really matter to the rest of your application. The choice of how to handle an exception is completely orthogonal to the rest of the application.

(As an aside, this is not how I would approach configurable policy-based exception-handling. I would tends more towards an AOP style, such as registering an exception-logger interceptor in the container.)


I run into this problem when I am developing functions that have no recoverable state. I believe this policy driven exception handling is actually useful and ensures that all the other developers that are part of this project actually adhere to a standard for non-recoverable exceptions.

I agree with the posters above, you may want to stay away from policy based exceptions if you are using them for control flow.


I have to agree with the statement that "the exception handling block solves problems that really don't exist in practice." I've used the block since its release and I rarely feel like I'm actually gaining much by using it. Well, perhaps a bit of a headache. :)

Before starting, I will admit that I do like the Exception Shielding at WCF Service Boundaries functionality. However, that was added fairly recently, involves no coding -- only attributes and configuration, and is not how the block is usually sold. This is how Microsoft shows it at http://msdn.microsoft.com/en-us/library/cc309250.aspx

alt text

To my eyes the above is flow control.

try
{
  // Run code.
}
catch(DataAccessException ex)
{
    bool rethrow = ExceptionPolicy.HandleException(ex, "Data Access Policy");
    if (rethrow)
    {
        throw;
    }
}

When you combine the flow control aspect with the code above you are definitely not making wrong code look wrong. (Never mind that the if (rethrow) construct does not offer very much abstraction.) This can make maintenance more difficult for developers unfamiliar with the policy definitions. If the postHandlingAction in the configuration file is changed (it will probably happen at some point) you will probably find the application behaving in unexpected ways that have never been tested.

Perhaps I wouldn't find it as objectionable if the block did not handle flow control but simply allowed you to chain handlers together.

But perhaps not. I don't actually recall ever being asked to:

  • add a new piece of functionality when handling an exception (e.g. in addition to logging to the event log also send an email. Actually, the logging block can do that on its own if you were already logging the exception yourself. :) )
  • change the exception handling behavior (swallow, rethrow, or throw new) across an entire "policy".

I'm not saying that it doesn't happen (I'm sure someone has a story!); I just feel that the Exception Handling Application Block makes programs harder to understand and maintain and this usually outweighs the functionality provided by the block.