When using services an important best practice is to keep details of exceptions from leaking beyond the service boundary.  Letting such details out of the boundary could create unnecessary coupling between the service callers and the service and would expose internal details of the service that you may wish to keep hidden.

Microsoft Patterns & Practices Enterprise Library (EL) provides an extension to the Exception Handling Application Block that hooks directly into WCF to provide the capability to replace service exceptions with custom faults.

Configuring Shielding

Exception shielding requires you to configure a Exception Handling Application Block with an exception policy.  The policy consists of the exceptions you want to handle and a post-handling action for each exception.  To work with the WCF Exception Shielding you need to set each exceptions post-handling action to ThrowNewException.

image

Once you have your basic policy set up you need to add a Fault Contract Exception Handler to each exception in your policy.

image

You can map properties from the exception thrown to the Fault you return.  This is set up in the PropertyMapping as the following screenshot indicates.  Source represents the source property on the Exception and Name is the property name on your fault to map to the source.  In this case the WidgetNotFoundException has a “Message” property which we will map to the “Details” property on our WidgetNotFoundFault.

image

Lastly, you need to mark your Service Class with the ExceptionShielding Attribute and give it the name of your exception policy.

image

Once everything is wired up you can test the service to see your exceptions get replaced by the fault contract types. 

A Quick Integration Test

When I fired up the service in Visual Studio 2010 and used the WCF Test Client, I ran a quick test to find a widget with the name of “Whatzit”.  The service had something to say about that request:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header />
  <s:Body>
    <s:Fault>
      <faultcode>s:Client</faultcode>
      <faultstring xml:lang="en-US">Widget Whatzit not found!</faultstring>
      <detail>
        <WidgetNotFoundFault           xmlns="http://schemas.datacontract.org/2004/07/ExceptionShieldingService2"
          xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
          <Details>Widget Whatzit not found!</Details>
        </WidgetNotFoundFault>
      </detail>
    </s:Fault>
  </s:Body>
</s:Envelope>

You can also test this using something like MSTest and decorating your integration test with [ExcpectedException(typeof(FaultContract<MyServiceReference.MyFaultType>)].  Just point the FaultContract<TDetail> to the type from your ServiceReference.  You can’t test fault contracts (to my knowledge) by calling the service imlementation class directly, you’ll need to do this by adding a service reference and calling the service that way.

Tips & Common Errors

After setting up a few of these I have run into some configuration problems which seem to be the most common issue hit with any of the EL blocks.

  • Use the Enterprise Library “Load from assembly” option to select your Exception and Fault Contract types.  EL seems particularly sensitive to using the fully-qualified assembly name including version & public key token.
  • Turn on some type of logging while testing your policy.  This will help you troubleshoot problems with the policy (mismatched types, etc).
  • “The current build operation (…) failed: Value cannot be null” Parameter name: faultContractType – This error stems from EL not being able to resolve your Fault Contract Type.  This is typically due to a bad mapping of your Fault Contract Type.  Check the Type Name, Assembly and version info to make sure it is correct.  Your best bet is to use the EL Config Editor to browse and select your fault type.