tags:

views:

1647

answers:

3

I have a WCF service that if something goes wrong throws a generic FaultException. I don't know why, sometimes the clients will catch a non-generic FaultException instead of the generic exception.

Does anybody know, what the problem is?

+1  A: 

Your service needs to handle all exceptions and wrap them into FaultException<T> where T is a data contract you have written. So the first step is to define a custom data contract that will contain your exception information:

[DataContract]
public class CustomFault
{
    public string Message { get; set; }
}

Then you instruct your service contract that its methods could potentially throw FaultException<CustomFault>. This allows the service to expose the CustomFault class in the wsdl, so that clients could generate a proxy class:

[ServiceContract]
public interface IMyServiceContract
{
    [FaultContract(typeof(CustomFault))]
    void MyMethod(string someArgument);
}

Next step is to implement this interface:

public class MyService : IMyServiceContract
{
    public void MyMethod(string someArgument)
    {
        // Do something here that could throw exceptions but don't catch yet
    }
}

To handle exceptions you could implement IErrorHandler which will be used whenever one of your service methods throws an exception. The purpose of this error handler is to wrap the exception into FaultException<CustomFault>:

public class MyErrorHandler : IErrorHandler
{
    public bool HandleError(Exception error)
    {
        return true;
    }

    public void ProvideFault(Exception error, MessageVersion version, ref Message msg)
    {
        var customFault = new CustomFault()
        {
            Message = error.Message,
        };
        var fe = new FaultException<CustomFault>(customFault);
        MessageFault fault = fe.CreateMessageFault();
        string ns = "http://somenamespace/whatever";
        msg = Message.CreateMessage(version, fault, ns);
    }
}

Once you have registered your error handler, on the client side, you will always get FaultException<CustomFault>.

Darin Dimitrov
The wierd thing is that the same exception, sometimes throws as a non-generic FaultException.
Mohammadreza
A: 

The non-generic FaultException is thrown when the service throws some other exception that is not caught. You'll need to find out what the exception is and fix it if it's a bug, or else decide it's something you want to expose your clients to, then wrap it in a generic FaultException and add a FaultContract appropriately.

John Saunders
A: 

another possibility is that your TDetail is not being serialized properly. This may be the case if e.g. TDetail derives from Exception and you have an inner exception that is not serializable.

mostlytech