Aggregate Exception and WCF

I call the WCF service, which, under certain conditions, throws an AggregateException with all the problems that occurred with the call

On the other hand, I get a FaultException (this makes sense because WCF only understands these exceptions). The problem is that the part for the contract is not a cumulative exception. As if by default, WCF gets the first exception for the AggregateException (InnerExceptions) exception list and encapsulates it. So on the client side, I just get the first exception from the list. After learning the bits, I did the following:

Added this to the contract.

[FaultContract(typeof(AggregateException))] 

Then to call the service ..

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

But on the other hand, this is:

 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; } 

Instead, it gets into the Exception statement and receives such an error (which, obviously, is some random error, because I have no connection problems, and debugging 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?

+6
source share
2 answers

Evil, your mistake is due to an exception. Read Using the special FaultContract object containing System.Exception results in the Add Service Link error - mho. for instance

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

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

+1
source

I suspect your problem occurs before you get into the BaseService code, so that you are not actually throwing an AggregateException. You need to determine which exception is thrown, the easiest way is debugging on the server, the next easiset is to enable some logging.

If you want to be able to easily track this material and be able to manipulate errors, etc., it is best to implement IErrorHandler, the 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. } } 

Please note that the above code is not suitable for your AggregateException exactly, but you will get the correct path, you will also need to enter an error handler if you decide to go along this route.

0
source

Source: https://habr.com/ru/post/889688/


All Articles