Thursday 5 March 2009

WCF Exceptions and Faults

In Windows Communication Foundation (WCF) exceptions thrown from services have to be converted into Faults - which are basically cross domain friendly exceptions. Custom faults can be created and are just declared using the [DataContract] attribute. The example below shows the declaration of a simple Fault.
[DataContract]
public class MyFault
{
[DataMember]
public string Message { get; set; }

public PasswordFault()
{
}

public PasswordFault(string message)
{
this.Message = message;
}
}
To generate a WCF fault you have to use the FaultException class. The example below shows how we could raise the fault declared in the previous example.
public class myService: IMyContract
{
public void MyMethod
()
{
try
{
......
{
catch (myException exc)
{
MyFault = new MyFault(exc.Message);
throw new FaultException(MyFault, "Failed to run MyMethod");
}
}
}
One other important part of setting up faults in WCF is that the OperationalContract of the method raising the fault needs to define the the FaultContracts that the method can raise. For example we might define the service contract of our service to be as follows:
[ServiceContract]
public interface IMyContract
{
[OperationContract]
[FaultContract(typeof(AuthenticationFault))]
void MyMethod();
}
The FaultContract attribute is telling WCF which faults can be expected. If a fault is thrown that is not defined here, the client will just get an ambiguous FaultException raised and be unable to access the extra data defined in the Fault.

Alternative Fault Handling Techniques

Recently, during the development of quite a large SOA based system I noticed that Faults that are raised by sub-services were not being raised correctly through the next service. The only way to ensure that these faults were received by the client was to recapture the fault (as a FaultException() ) and re throw them!

After a bit of investigation and a very helpful reply to a post on the MSDN WCF forum I was pointed in the direction of this example of using the IErrorHandler interface to add custom error handlers to the individual channel dispatcher. I'm not going to go into any great amount of detail about this, but I strongly recommend reading the article. It gives you a much more elegant way of handling exception to fault conversions in WCF.

No comments: