WCF throwing CommunicationException when FaultException is thrown

Andy Hunt picture Andy Hunt · Jul 1, 2011 · Viewed 7.4k times · Source

Solution:

A bit of tracing showed the CommunicationException was being thrown because there was an issue with my exception T not serializing correctly; because, two layers deep, I had an anonymously typed object, which was unserializable. Removing it and bubbling up the changes appeared to fix it. There was somethinge else small I did before that, but I can't remember for the life of me what it was, only that it wasn't done in the config.

I was getting messages from my traces such as:

Type 'RebuiltWCFService.Requests.HelloWorldRequest' with data contract name 'HelloWorldRequest:http://schemas.datacontract.org/2004/07/RebuiltWCFService.Requests' is not expected. 
Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.

Original post

I've encountered a seemingly strange issue today that I just cant't find an answer to!

The problem: my service is throwing a CommunicationException when I throw a FaultException! It does not do this if I don't throw an exception.

In my service, I'm properly defining the fault contracts:

[OperationContract]
[FaultContract(typeof(Faults.HelloWorldFault))]
Responses.HelloWorldResponse HelloWorld(Requests.HelloWorldRequest parameter);

Then under error conditions I'm throwing an exception of the correct type:

if (_errors.Count() > 0)
{
    Faults.HelloWorldFault fault = new Faults.HelloWorldFault(_errors);
    throw new FaultException<Faults.HelloWorldFault>(fault, new FaultReason("There are one or more errors in the request. Check the 'Errors' property for more detaisl"));
}

And then I'm catching it on the client end:

try
{
    response = client.HelloWorld(new BasicService.HelloWorldRequest() { Number = 49 });
    client.Close();
    Console.WriteLine(String.Format("Response message: {0}, Response number: {1}", response.Message, response.Number));
}
catch (FaultException<BasicService.HelloWorldFault> ex)
{
    ...
}

That all seems OK to me, and like it should work. However, as soon as I go to test my error clauses (by providing bad data, such as a missing field), the whole thing dies on me. When I throw my FaultException, the service instead throws a CommunicationException with the message

An error occurred while receiving the HTTP response to http://localhost:8732/Design_Time_Addresses/RebuiltWCFService/Service1/. 
This could be due to the service endpoint binding not using the HTTP protocol. 
This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down). 
See server logs for more details.

Can anybody offer some insight on this one? I am using the basicHttp binding, and I've also tried it with wsHttp. I will post my config file upon request.

Answer

SaravananArumugam picture SaravananArumugam · Jul 1, 2011

A FaultException is a child of CommunicationException. So there is nothing wrong in what's happening in your code.

If you are uncertain about what the exception is while handling, it is usually reported as CommunicationException. If you want to handle your specific exception in your own way, use the following structure.

try
{ ... }
catch (FaultException<MyDemoException> me)
{ ... }
catch (FaultException fe)
{ ... }
catch (CommunicationException ce)
{ ... }
catch (Exception ex)
{ ... }

In the above structure, Exception is parent of CommunicationException. CommunicationException is the parent of FaultException and so on.

System.Object 
  System.Exception
    System.SystemException
      System.ServiceModel.CommunicationException
        System.ServiceModel.FaultException
          System.ServiceModel.FaultException<TDetail>
            System.ServiceModel.Web.WebFaultException<T>