WCF CommunicationException with no Exception message details
Asked Answered
U

1

4

One of the things I never understood about WCF is why no Exception message details are propagated back to the calling client when the server encounters an unhandled exception.

For example, if I have the following server code

[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class Server : IServer
{
    public DTO GetDTO()
    {
        DTO dto = new DTO();
        dto.dto = dto;
        return dto;
    }

}

public class DTO
{
    public DTO dto;
}

[ServiceContract]
public interface IServer
{
    [OperationContract]
    DTO GetDTO();
}

I deliberately introduced an ObjectGraph to cause a serialization exception when the DTO object is returned.

If I have a client that calls this Server's GetDTO() method, I will get the following CommunicationException.

The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:00:58.9350000'.

Which is absolutely useless. It has no inner exception and not even the real exception message.

If you then use Microsoft Service TraceViewer, you will see the exception but you must turn on the Diagnostics tracing for this.

The exception message that should be sent back is

There was an error while trying to serialize parameter http://tempuri.org/:GetDTOResult. The InnerException message was 'Object graph for type 'TestWCFLib.DTO' contains cycles and cannot be serialized if reference tracking is disabled.'. Please see InnerException for more details.

So can anybody tell me how get the right exception message show up on the client side? Obviously, setting IncludeExceptionDetailInFaults to true doesn't make a difference.

Unprintable answered 13/9, 2011 at 15:29 Comment(1)
I found that I had IncludeExceptionDetailInFaults set in the config file, but it was getting overridden by the data-annotation you've highlighted here. Another place you can check is in the Error Pages configuration for your IIS site. I set 500 error feature settings to be detailed messages always.Federal
G
2

I think that it is by design that the server errors are not propogated to client. This is in general a practice to not expose server internals to clients as the main purpose of Client Server architecture is independence of server.

You can still achieve this by using Fault Exception

Decorate your service declaration with a fault contract

[ServiceContract]
public interface IServer
{
    [OperationContract]
    [FaultContract(typeof(MyApplicationFault))]
    DTO GetDTO();
}

Then catch errors in servcie implementation and throw a fault exception.

[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
    public class Server : IServer
    {
        public DTO GetDTO()
        {
            try
              {
                   DTO dto = new DTO();
                   dto.dto = dto;
                   return dto;
               }
            catch (Exception ex)
                 {
                     MyApplicationFault fault = new MyApplicationFault(...);
                     throw new FaultException<MyApplicationFault>(fault);
                 }
        }

    }

And catch the exception in client

IServer proxy = ...;    //Get proxy from somewhere
try 
{
    proxy.GetDTO();
}
catch (TimeoutException) { ... }
catch (FaultException<MyApplicationFault> myFault) {
    MyApplicationFault detail = myFault.Detail;
    //Do something with the actual fault
}
catch (FaultException otherFault) { ... }
catch (CommunicationException) { ... }

Hope this helps. For a nice tutorial please see Code Project Tutorial on Fault Exception

Galilee answered 4/12, 2012 at 8:34 Comment(1)
CommunicationException is the supertype von FaultException so the order of the catches should be changed.Retardant

© 2022 - 2024 — McMap. All rights reserved.