IsmailS
IsmailS

Reputation: 10863

Catches communication exception instead of custom fault exception - WCF

On Server I'm throwing the exception like this.

catch(SqlException exception)
{
  if (exception.Message.Contains("Custom error from stored proc"))
  {
    //Exception to be thrown when authentication fails.
    throw new FaultException<MyServiceFault>(new MyServiceFault { MessageText = exception.Message });
  }
}

And on client end I'm catching the exception

catch(FaultException<MyServiceFault> faultException)
{

}

Here is my MyServiceFault

[DataContract]
public class MyServiceFault  
{
  [DataMember]
  public string MessageText { get; set; }

  [DataMember]
  public Guid Id { get; set; }
}

The problem is that on client, it doesn't go to MyServiceFault catch block instead it goes to communication exception catch block and throws this error

System.ServiceModel.CommunicationException: The underlying connection was closed: The connection was closed unexpectedly. ---> System.Net.WebException

I've also decorated my service method [FaultContract(typeof(MyServiceFault))] in the interface which is implemented by my service.

In my web.config servicebehaviour tag consist <serviceDebug includeExceptionDetailInFaults="true" />

Any idea where I'm going wrong.

This problem is occurring on windows 7. Can there be a reason related to it?

IMPORTANT UPDATE
According to answerers, any unhandled exception on the server can cause throwing of the Communication exception on the client side and it may not have anything to do with the custom fault exception you have thrown on the server. So the solution is log the errors on the server and find what error is causing this behavior. Here is a very useful open source logging functionality I found and implemented which can even be more useful after your project goes into production environment. Many thanks to the answerers.

A better way of logging exceptions in WCF

Upvotes: 2

Views: 6241

Answers (3)

AndiDog
AndiDog

Reputation: 70228

As a follow-up, one reason for getting CommunicationException is that the FaultException could not be serialized correctly. In the log (see Simon's answer on how to set up logging), this would show up as "Handling exception" followed by "Replying to an operation threw an exception".

In my case, this was caused by not initializing an enumeration value:

[DataContract]
public class MyCustomWebServiceFault
{
    public MyCustomWebServiceFault()
    {
    }

    [DataMember]
    public EMyCustomWebServiceFaultReason Reason { get; set; }

    [...]

The log then revealed it:

Enum value '0' is invalid for type 'EMyCustomWebServiceFaultReason' and cannot be serialized. Ensure that the necessary enum values are present and are marked with EnumMemberAttribute attribute if the type has DataContractAttribute attribute.

Long story short, use logging or unit test exception serialization.

Upvotes: 4

Simon P Stevens
Simon P Stevens

Reputation: 27509

Add logging to your WCF calls by including this in your app.config.

<system.diagnostics>
  <trace autoflush="true" />
  <sources>
    <source name="System.ServiceModel" switchValue="Information, ActivityTracing">
      <listeners>
        <add name="sdt" type="System.Diagnostics.XmlWriterTraceListener" initializeData="c:\LogPath\LogFile.svclog" />
      </listeners>
    </source>
  </sources>
</system.diagnostics>

(You can do this for both server and client, obviously specifying different log files)

Once you've generated some logs, look through for exceptions or warnings. I often find this produces some very useful information that helps me solve WCF problems.

To read the log file, you'll need to use SvcTraceViewer.exe. Unfortunately the only way to get this is with the windows SDK which is a bit of a big download for one tiny little tool.

It's also worth bearing in mind that WCF can through the CommunctionException when it is being closed, and this is expected behaviour. You shouldn't just do using with client WCF comm channels. Instead, you should follow a pattern like this:

try{
    x.Close()
}
catch(Comms ex){
    x.Abort()
}

Upvotes: 7

Terry
Terry

Reputation: 5282

One thing i learned from working with wcf is that the error CommunicationException is thrown alot of times. It is even possible that the error you get has nothing to do with the Exception you throw, but with something else causing it. At the moment something is being sent between a client and server, it's hard to track down what is causing the exception.

I could solve some of my issues by adjusting some settings in the app.config. Setting timeout, etc...

Maybe that can help?

Upvotes: 4

Related Questions