6

I'm calling a WCF service, which under certain conditions returns an AggregateException, with all the problems that happened through the call

On the other side, I'm getting a FaultException (which makes sense, because WCF understands only about these exceptions). The problem is, the Detail for the contract is not an aggregate exception. It's as if by default, WCF gets the 1st exception for the AggregateException list of exceptions (InnerExceptions), and encapsulates that. So on the client side, i'm just getting the first exception of the list. After investigating a bit, i did the following :

Added this to the contract

[FaultContract(typeof(AggregateException))]

Then on the service call..

try
{
    BaseService.Blabla.Delete(item);
}
catch (AggregateException ex)
{
    throw new FaultException<AggregateException>(ex);
}  

But on the other side, which is this :

catch (FaultException<AggregateException> ex)
{
    string msg = string.Empty;
    foreach (var innerException in ex.Detail.InnerExceptions)
    {
        msg += innerException + Environment.NewLine;
    }
    MessageBox.Show(msg);
}
catch (Exception ex)
{
    throw ex;
}

It's getting into the Exception catch statement instead, and getting an error like this (which is obviously some random error, because i don't have any connection issues, and debugging this returns immediately, 4 minutes never pass) :

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:03:59.9939994'. : An existing connection was forcibly closed by the remote host

What am i missing?

Daniel Perez
  • 4,292
  • 4
  • 29
  • 54

2 Answers2

1

The evil is, your fault detail derives from exception. Read Using custom FaultContract object containing System.Exception causes 'Add Service Reference' to fail – mho. For example

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

then FaultException<AggregateFault > works perfect but not FaultException<AggregateException>

Community
  • 1
  • 1
Om Deshmane
  • 808
  • 6
  • 11
-1

I suspect your problem is ocurring before you ever hit the BaseService code, so you are not actually throwing an AggregateException. You need to determine what exception is being thrown, the easiest way is by debugging on the server, the next easiset is to hook up some logging.

If you want to be able to easily track this stuff and have the ability to manipulate faults etc the best bet is to implement IErrorHandler, a basic implementation that I use usually goes along the following lines:

public class ErrorHandler : IErrorHandler
{
    private readonly Action<Exception> LogException;
    private readonly Action<Message> LogFault;

    public ErrorHandler(Action<Exception> logException, Action<Message> logFault)
    {
        LogException = logException;
        LogFault = logFault;
    }

    public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
    {
        if (error is FaultException) // Thrown by WCF - eg request deserialization problems, can be explicitly thrown in code
        {
            LogFault(fault);
            return;
        }

        var faultCode = new FaultCode("UnknownFault");
        if (error is ArgumentOutOfRangeException)
        {
            faultCode = new FaultCode("ArgumentOutOfRange");
        }

        var action = OperationContext.Current.IncomingMessageHeaders.Action;
        fault = Message.CreateMessage(version, faultCode, error.Message, action);
        LogFault(fault);
    }

    public bool HandleError(Exception error)
    {
        // Logging of exceptions should occur here as all exceptions will hit HandleError, but some will not hit ProvideFault
        LogException(error);

        return false; // false allows other handlers to be called - if none return true the dispatcher aborts any session and aborts the InstanceContext if the InstanceContextMode is anything other than Single.
    }
}

Note the above code wont cater for your AggregateException exactly but will get you on the right track, you will also need to inject the error handler if you choose to go down this route.

dice
  • 2,820
  • 1
  • 23
  • 34