Monday, October 1, 2012

WCF Service Exception Handling Best Practice

I was working on a WCF service and I needed a way to handle uncaught exception raised during any service operation in a controlled way e.g. I wanted to log or email unhandled exception and send a valid response to client with information required to trace the problem.

One way was to have a try catch in each method and return the fault from there. This approach is simple and works however in case of lots of service operations or lots of services it become very tedious to repeat the same code block everywhere.

So I searched and finally implemented a new common error handler for my service based on WCF interface IErrorHandler. This interface provides two methods HandleError and ProvideFault which you can override to implement your own logic. Once hooked into your service, for any uncaught exception HandleError and ProvideFault methods are invoked. HandleError is the method where you log the errors, and ProvideFault creates a new fault message which becomes your service response.

There are two ways you can hook this handler to your service:
1) using Service Behavior attributes by implementing IServiceBehavior interface and inheriting from Attribute class. and then use the attribute on your service class similar to any other attribute

2) Use service behavior extension by inheriting from BehaviorExtensionElement, which allows to configure common error handler via service web.config file

I have attached here the complete code of this common handler. In order to use this either use method 1 or 2. A sample on how to use is given in ErrorBehaviorAttribute and ErrorBehaviorExtension classes as well.


Please note, this sample code also gives you a common ServiceException class which you need to use as faultContract type in your service contract e.g.
[FaultContract(typeof(ServiceException), Name = "serviceFault")]

If you decide to use this Common Error Handler, The same ServiceException should be used to return your business exceptions. You can always change implementation of these anytime you want, this code only gives you an idea on how to implement these.

Also last but not least, in order to upload the sample to make it available to all of you, I made some changes e.g. namespace and all you may want to change them as per your need.

Happy coding :-)