views:

810

answers:

3

In the most recent version (4.1, released October 2008) of The Microsoft Enterprise Library's Exception Handling Application Block, there are two HandleException() method signatures, and I am a bit lost on the intent for these, especially since neither the documentation, intellisense, nor the QuickStart apps intimate any meaningful difference.

Here are the two signatures:

bool HandleException(Exception exceptionToHandle, string policyName);

bool HandleException(Exception exceptionToHandle, string policyName, out Exception exceptionToThrow);

All of the examples I have found use the first, as in this example straight out of the XML documentation comments on the actual method:

try
{
   Foo();
}
catch (Exception e)
{
   if (ExceptionPolicy.HandleException(e, name)) throw;
}

And here, from the same source (the XML doc comments for the method), is an example of using the second:

try
{
   Foo();
}
catch (Exception e)
{
   Exception exceptionToThrow;
   if (ExceptionPolicy.HandleException(e, name, out exceptionToThrow))
   {
      if(exceptionToThrow == null)
         throw;
      else
         throw exceptionToThrow;
   }
}

So, my question is, what does using the second one give you that the first does not? This should probably be obvious to me, but my head is a mess today and I don't really want to keep banging my head against the proverbial wall any longer. :)

No speculations, please; I hope to hear from someone that actually knows what they are talking about from experience using this.

+2  A: 

If you use a replace handler in the enterprise library config, your replacement exception is returned by means of the second signature .. , out Exception exceptionToThrow).

Paul Berry
I am going to accept your answer in order to close this, since no one seems to care about this but me! For the given example, I don't see what value the second one adds - if you set up the configuration to wrap/replace the original exception, internally it could simply replace the one passed in (since it is passed by reference), since all exceptions are polymorphic with System.Exception, and that would be all that needs to be done. I can contrive some instances where maybe you want to keep the original one around, but that would be easy enough to do with a temp variable if really needed.
Jason Bunting
By the way, I gave you a +1 since you did answer the question and your answer is valid. My gripe is mainly that I don't see a need for the overload.
Jason Bunting
A: 

I believe you are not allowed to throw your original exceptions across WCF service boundaries, this is a security feature (really to make sure that sensitive error information is not propagated through the service chain). Therefore a new execption can be created and passed in via the second parameter out Exception exceptionToThrow) and given a specific exception message and type by means of your configuration (enterprise library replace exception). One example of which is:

            try
            {
                throw new InvalidCastException();
            }
            catch (InvalidCastException ex)
            {
                Exception ex1;
                bool rethrow = ExceptionPolicy.HandleException(ex, "ReplacePolicy1", out ex1);

                if (rethrow)
                {
                    throw new FaultException<ApplicationException>((ApplicationException)ex1, ex1.Message);
                }
            }

Throwing a FaultException (with a Fault contract set up on the WCF operation) prevents the WCF Service from reporting a faulted state error message in your calling application / Service.

Without the second signature i would struggle with error simplification / propagation across WCF service boundries.

Thanks, Paul. (mod to code 8/7/09 - correction comment from John, thanks)

Paul Berry
Paul, you're using it incorrectly. First, you don't need to use ex1 = new Exception() since you're about to overwrite it. Next, rethrow==true means to throw what the HandleException passes you in ex1, not to throw your own. If you want to throw FaultException<ApplicationException>, then you should configure it.
John Saunders
John, it should be (Exception ex1;) yes.Your second statement:i have found when throwing an exception through WCF service boundaries, i have to throw it as a FaultExecption, otherwise the service will go into a faulted state, although you can configure a rethrow expection type as a faultexecption, i can't seem to specify a specific faultexception type (ie:FaultException<ApplicationException>) in config.I throw the specific type so my calling service can catch a specific Faultexception type.Your comments are sound if not pushing exception through WCF service boundries as i am doing
Paul Berry
+1  A: 

The main difference between the two method overloads is that

bool HandleException(Exception exceptionToHandle, string policyName);

will throw an exception if the PostHandlingAction is set to ThrowNewException.


Whereas the second method overload:

bool HandleException(Exception exceptionToHandle, string policyName, out Exception exceptionToThrow);

does not throw an exception in that case but instead returns the exception to be rethrown as an out parameter.

Actually, both calls invoke the same core code but the second method overload catches the thrown Exception and returns it to the caller.

So the second overload gives you a bit more control since you could perform some additional logic before throwing. It also standardizes the API in the sense that if you use the second HandleException method with the out parameter Enterprise Library will never intentionally handle your exception and throw it for you. i.e. The first method sometimes throws and sometimes relies on you to rethrow (in the case of NotifyRethrow) but the second method always returns and lets the caller throw/rethrow.

Tuzo