bool IExceptionHandler.TryHandleException(ExceptionInformation exceptionInformation, OperationRetrySettings retrySettings, out ExceptionHandlingResult result)
 {
     if (exceptionInformation.Exception is FabricNotPrimaryException)
     {
         if (exceptionInformation.TargetReplica == TargetReplicaSelector.Default)
         {
             result = new ExceptionHandlingRetryResult(exceptionInformation.Exception, false, retrySettings, int.MaxValue);
             return(true);
         }
         //ServiceTrace.Source.WriteInfo(ServiceRemotingExceptionHandler.TraceType, "{0} Got exception {1} which does not match the replica target : {2}", (object) this._traceId, (object) exceptionInformation.Exception, (object) exceptionInformation.TargetReplica);
         result = null;
         return(false);
     }
     if (exceptionInformation.Exception is FabricNotReadableException)
     {
         result = new ExceptionHandlingRetryResult(exceptionInformation.Exception, false, retrySettings, int.MaxValue);
         return(true);
     }
     if (exceptionInformation.Exception is FabricTransientException)
     {
         result = new ExceptionHandlingRetryResult(exceptionInformation.Exception, true, retrySettings, int.MaxValue);
         return(true);
     }
     result = null;
     return(false);
 }
示例#2
0
        /// <summary>
        /// Method that examines the exception and determines how that exception can be handled.
        /// </summary>
        /// <param name="exceptionInformation">Information about the exception</param>
        /// <param name="retrySettings">The operation retry preferences.</param>
        /// <param name="result">Result of the exception handling</param>
        /// <returns>true if the exception is handled, false otherwise</returns>
        bool IExceptionHandler.TryHandleException(
            ExceptionInformation exceptionInformation,
            OperationRetrySettings retrySettings,
            out ExceptionHandlingResult result)
        {
            var e = exceptionInformation.Exception;

            if (e is ActorConcurrencyLockTimeoutException)
            {
                if (ActorLogicalCallContext.IsPresent())
                {
                    result = new ExceptionHandlingThrowResult()
                    {
                        ExceptionToThrow = e
                    };
                    return(true);
                }

                result = new ExceptionHandlingRetryResult(
                    e,
                    true,
                    retrySettings,
                    retrySettings.DefaultMaxRetryCount);
                return(true);
            }

            result = null;
            return(false);
        }
            private static bool TryHandleFabricException(
                FabricException fabricException,
                OperationRetrySettings retrySettings,
                out ExceptionHandlingResult result)
            {
                if ((fabricException is FabricCannotConnectException) ||
                    (fabricException is FabricEndpointNotFoundException)
                    )
                {
                    result = new ExceptionHandlingRetryResult(
                        fabricException,
                        false,
                        retrySettings,
                        int.MaxValue);
                    return(true);
                }

                if (fabricException.ErrorCode.Equals(FabricErrorCode.ServiceTooBusy))
                {
                    result = new ExceptionHandlingRetryResult(
                        fabricException,
                        true,
                        retrySettings,
                        int.MaxValue);
                    return(true);
                }

                result = null;
                return(false);
            }
        public bool TryHandleException(ExceptionInformation exceptionInformation, OperationRetrySettings retrySettings, out ExceptionHandlingResult result)
        {
            this.logger.LogError("retry {RetryAttempt} for {replica}: {exception}", retrySettings.RetryPolicy.TotalNumberOfRetries, exceptionInformation.TargetReplica.ToString(), exceptionInformation.Exception.Message);

            if (IsNotTransient(exceptionInformation))
            {
                this.logger.LogError(exceptionInformation.Exception, "A known non-transient exception occurred on retry {RetryAttempt} for {replica}: {exception}", retrySettings.RetryPolicy.TotalNumberOfRetries, exceptionInformation.TargetReplica.ToString(), exceptionInformation.Exception.Message);
                result = new ExceptionHandlingRetryResult(exceptionInformation.Exception, TransientException.IsNotTransient, TimeSpan.FromSeconds(1), retrySettings.DefaultMaxRetryCountForNonTransientErrors);
                return(true);
            }

            // if exceptionInformation.Exception is known and is transient (can be retried without re-resolving)
            if (IsTransient(exceptionInformation))
            {
                this.logger.LogError(exceptionInformation.Exception, "A known transient exception occurred on retry {RetryAttempt} for {replica}: {exception}", retrySettings.RetryPolicy.TotalNumberOfRetries, exceptionInformation.TargetReplica.ToString(), exceptionInformation.Exception.Message);
                result = new ExceptionHandlingRetryResult(exceptionInformation.Exception, TransientException.IsTransient, TimeSpan.FromSeconds(1), retrySettings.DefaultMaxRetryCountForTransientErrors);
                return(true);
            }


            // if exceptionInformation.Exception is unknown (let the next IExceptionHandler attempt to handle it)
            this.logger.LogError(exceptionInformation.Exception, "A unknown exception occurred on retry {RetryAttempt} for {replica}: {exception}", retrySettings.RetryPolicy.TotalNumberOfRetries, exceptionInformation.TargetReplica.ToString(), exceptionInformation.Exception.Message);
            result = null;
            return(false);
        }
 protected bool HandleRemoteException(Exception e, out ExceptionHandlingResult result)
 {
     if (e is FabricTransientException)
     {
         result = new ExceptionHandlingRetryResult
         {
             IsTransient = true,
             RetryDelay = TimeSpan.FromMilliseconds(ThreadSafeRandom.Value.NextDouble() * WcfFactory.MaxRetryBackoffIntervalOnTransientErrors.TotalMilliseconds)
         };
         return true;
     }
     if (e is FabricNotPrimaryException)
     {
         result = new ExceptionHandlingRetryResult
         {
             IsTransient = false,
             RetryDelay = TimeSpan.FromMilliseconds(ThreadSafeRandom.Value.NextDouble() * WcfFactory.MaxRetryBackoffIntervalOnNonTransientErrors.TotalMilliseconds)
         };
         return true;
     }
     result = new ExceptionHandlingThrowResult
     {
         ExceptionToThrow = new AggregateException(e)
     };
     return true;
 }
        public bool TryHandleException(ExceptionInformation exceptionInformation, OperationRetrySettings retrySettings, out ExceptionHandlingResult result)
        {
            if (exceptionInformation.Exception is RpcException rpcEx)
            {
                switch (rpcEx.Status.StatusCode)
                {
                case StatusCode.Unavailable when rpcEx.Status.Detail == "Endpoint read failed":
                    Log.LogInformation(exceptionInformation.Exception, "Throwing: {Exception}", exceptionInformation.Exception.Message);
                    result = new ExceptionHandlingThrowResult();
                    return(true);

                case StatusCode.Unavailable:
                case StatusCode.Unknown:
                case StatusCode.Cancelled:
                    Log.LogInformation(exceptionInformation.Exception, "Not transient exception: {Exception}, Retry {@Retry}", exceptionInformation.Exception.Message, retrySettings);
                    result = new ExceptionHandlingRetryResult(exceptionInformation.Exception, false, retrySettings, int.MaxValue);
                    return(true);

                default:
                    Log.LogInformation(exceptionInformation.Exception, "Unknown exception: {Exception}, Retry {@Retry}", exceptionInformation.Exception.Message, retrySettings);
                    result = new ExceptionHandlingThrowResult();
                    return(true);
                }
            }
            else
            {
                Log.LogInformation(exceptionInformation.Exception, "Throwing: {Exception}", exceptionInformation.Exception.Message);
                result = new ExceptionHandlingThrowResult();
                return(true);
            }
        }
        private bool CreateExceptionHandlingRetryResult(bool isTransient, Exception ex, out ExceptionHandlingResult result)
        {
            result = new ExceptionHandlingRetryResult(
                exceptionId: ex.GetType().Name,
                isTransient: isTransient,
                retryDelay: TimeSpan.FromMilliseconds(_rand.NextDouble() * _options.MaxRetryBackoffInterval.TotalMilliseconds),
                maxRetryCount: _options.MaxRetryCount);

            return(true);
        }
        private bool CreateExceptionHandlingResult(bool isTransient, out ExceptionHandlingResult result)
        {
            result = new ExceptionHandlingRetryResult()
            {
                IsTransient = isTransient,
                RetryDelay  = TimeSpan.FromMilliseconds(MaxRetryBackoffIntervalOnNonTransientErrors.TotalMilliseconds),
            };

            return(true);
        }
        /// <summary>
        /// Method that examines the exception and determines how that exception can be handled.
        /// </summary>
        /// <param name="exceptionInformation">Information about the exception</param>
        /// <param name="retrySettings">The operation retry preferences.</param>
        /// <param name="result">Result of the exception handling</param>
        /// <returns>true if the exception is handled, false otherwise</returns>
        bool IExceptionHandler.TryHandleException(
            ExceptionInformation exceptionInformation,
            OperationRetrySettings retrySettings,
            out ExceptionHandlingResult result)
        {
            if (exceptionInformation.Exception is FabricNotPrimaryException)
            {
                if (exceptionInformation.TargetReplica == TargetReplicaSelector.PrimaryReplica)
                {
                    result = new ExceptionHandlingRetryResult(
                        exceptionInformation.Exception,
                        false,
                        retrySettings,
                        int.MaxValue);

                    return(true);
                }

                ServiceTrace.Source.WriteInfo(
                    TraceType,
                    "{0} Got exception {1} which does not match the replica target : {2}",
                    this.traceId,
                    exceptionInformation.Exception,
                    exceptionInformation.TargetReplica);

                result = null;
                return(false);
            }

            if (exceptionInformation.Exception is FabricNotReadableException)
            {
                result = new ExceptionHandlingRetryResult(
                    exceptionInformation.Exception,
                    false,
                    retrySettings,
                    int.MaxValue);

                return(true);
            }

            // Note: This code handles retries for FabricTransientException even from Actors, eg. ActorDeletedException.
            if (exceptionInformation.Exception is FabricTransientException)
            {
                result = new ExceptionHandlingRetryResult(
                    exceptionInformation.Exception,
                    true,
                    retrySettings,
                    int.MaxValue);

                return(true);
            }

            result = null;
            return(false);
        }
示例#10
0
        public bool TryHandleException(ExceptionInformation exceptionInformation, OperationRetrySettings retrySettings, out ExceptionHandlingResult result)
        {
            if (exceptionInformation.Exception is TimeoutException)
            {
                result = new ExceptionHandlingRetryResult(exceptionInformation.Exception, false, retrySettings, retrySettings.DefaultMaxRetryCount);
                return true;
            }
            else if (exceptionInformation.Exception is ProtocolViolationException)
            {
                result = new ExceptionHandlingThrowResult();
                return true;
            }
            else if (exceptionInformation.Exception is WebException)
            {
                WebException we = exceptionInformation.Exception as WebException;
                HttpWebResponse errorResponse = we.Response as HttpWebResponse;

                if (we.Status == WebExceptionStatus.ProtocolError)
                {
                    if (errorResponse.StatusCode == HttpStatusCode.NotFound)
                    {
                        // This could either mean we requested an endpoint that does not exist in the service API (a user error)
                        // or the address that was resolved by fabric client is stale (transient runtime error) in which we should re-resolve.
                        result = new ExceptionHandlingRetryResult(exceptionInformation.Exception, false, retrySettings, retrySettings.DefaultMaxRetryCount);
                        return true;
                    }

                    if (errorResponse.StatusCode == HttpStatusCode.InternalServerError)
                    {
                        // The address is correct, but the server processing failed.
                        // Retry the operation without re-resolving the address.
                        result = new ExceptionHandlingRetryResult(exceptionInformation.Exception, true, retrySettings, retrySettings.DefaultMaxRetryCount);
                        return true;
                    }
                }

                if (we.Status == WebExceptionStatus.Timeout ||
                    we.Status == WebExceptionStatus.RequestCanceled ||
                    we.Status == WebExceptionStatus.ConnectionClosed ||
                    we.Status == WebExceptionStatus.ConnectFailure)
                {
                    result = new ExceptionHandlingRetryResult(exceptionInformation.Exception, false, retrySettings, retrySettings.DefaultMaxRetryCount);
                    return true;
                }
            }

            result = null;
            return false;
        }
示例#11
0
        public bool TryHandleException(ExceptionInformation exceptionInformation, OperationRetrySettings retrySettings, out ExceptionHandlingResult result)
        {
            if (exceptionInformation.Exception is TimeoutException)
            {
                result = new ExceptionHandlingRetryResult(exceptionInformation.Exception, false, retrySettings, retrySettings.DefaultMaxRetryCount);
                return(true);
            }
            else if (exceptionInformation.Exception is ProtocolViolationException)
            {
                result = new ExceptionHandlingThrowResult();
                return(true);
            }
            else if (exceptionInformation.Exception is WebException)
            {
                WebException    we            = exceptionInformation.Exception as WebException;
                HttpWebResponse errorResponse = we.Response as HttpWebResponse;

                if (we.Status == WebExceptionStatus.ProtocolError)
                {
                    if (errorResponse.StatusCode == HttpStatusCode.NotFound)
                    {
                        // This could either mean we requested an endpoint that does not exist in the service API (a user error)
                        // or the address that was resolved by fabric client is stale (transient runtime error) in which we should re-resolve.
                        result = new ExceptionHandlingRetryResult(exceptionInformation.Exception, false, retrySettings, retrySettings.DefaultMaxRetryCount);
                        return(true);
                    }

                    if (errorResponse.StatusCode == HttpStatusCode.InternalServerError)
                    {
                        // The address is correct, but the server processing failed.
                        // Retry the operation without re-resolving the address.
                        result = new ExceptionHandlingRetryResult(exceptionInformation.Exception, true, retrySettings, retrySettings.DefaultMaxRetryCount);
                        return(true);
                    }
                }

                if (we.Status == WebExceptionStatus.Timeout ||
                    we.Status == WebExceptionStatus.RequestCanceled ||
                    we.Status == WebExceptionStatus.ConnectionClosed ||
                    we.Status == WebExceptionStatus.ConnectFailure)
                {
                    result = new ExceptionHandlingRetryResult(exceptionInformation.Exception, false, retrySettings, retrySettings.DefaultMaxRetryCount);
                    return(true);
                }
            }

            result = null;
            return(false);
        }
示例#12
0
        public bool TryHandleException(ExceptionInformation exceptionInformation, OperationRetrySettings retrySettings, out ExceptionHandlingResult result)
        {
            // if exceptionInformation.Exception is known and is transient (can be retried without re-resolving)
            //TODO: Add decision logic to determine whether exception is transient or not.
            result = new ExceptionHandlingRetryResult(exceptionInformation.Exception, true, retrySettings, retrySettings.DefaultMaxRetryCount);
            return(true);

            //// if exceptionInformation.Exception is known and is not transient (indicates a new service endpoint address must be resolved)
            //result = new ExceptionHandlingRetryResult(exceptionInformation.Exception, false, retrySettings, retrySettings.DefaultMaxRetryCount);
            //return true;

            //// if exceptionInformation.Exception is unknown (let the next IExceptionHandler attempt to handle it)
            //result = null;
            //return false;
        }
示例#13
0
        public bool TryHandleException(ExceptionInformation exceptionInformation, OperationRetrySettings retrySettings, out ExceptionHandlingResult result)
        {
            if (exceptionInformation == null)
            {
                throw new ArgumentNullException(nameof(exceptionInformation));
            }

            if (retrySettings == null)
            {
                throw new ArgumentNullException(nameof(retrySettings));
            }

            result = new ExceptionHandlingRetryResult(exceptionInformation.Exception, false, retrySettings, retrySettings.DefaultMaxRetryCount);

            return(true);
        }
        public bool TryHandleException(ExceptionInformation exceptionInformation, OperationRetrySettings retrySettings, out ExceptionHandlingResult result)
        {
            if (exceptionInformation == null)
            {
                throw new ArgumentNullException(nameof(exceptionInformation));
            }

            if (retrySettings == null)
            {
                throw new ArgumentNullException(nameof(retrySettings));
            }

            result = new ExceptionHandlingRetryResult(exceptionInformation.Exception, false, retrySettings, retrySettings.DefaultMaxRetryCount);

            return true;
        }
示例#15
0
            protected override bool OnHandleException(Exception ex, out ExceptionHandlingResult result)
            {
                //
                // TODO:
                // Analyze the given exception and return a proper result.

                result = new ExceptionHandlingRetryResult()
                {
                    ExceptionId   = ex.GetType().GUID.ToString(),
                    IsTransient   = false,
                    MaxRetryCount = 5,
                    RetryDelay    = TimeSpan.FromSeconds(1)
                };

                return(true);
            }
 public bool TryHandleException(
     ExceptionInformation exceptionInformation,
     OperationRetrySettings retrySettings,
     out ExceptionHandlingResult result)
 {
     if (exceptionInformation.Exception is InvalidOperationException)
     {
         result = new ExceptionHandlingRetryResult(exceptionInformation.Exception,
                                                   isTransient: true,
                                                   retryDelay: TimeSpan.FromSeconds(2),
                                                   maxRetryCount: 3);
         return(true);
     }
     result = new ExceptionHandlingThrowResult();
     return(false);
 }
 public bool TryHandleException(
     ExceptionInformation exceptionInformation,
     OperationRetrySettings retrySettings,
     out ExceptionHandlingResult result)
 {
     if (exceptionInformation.Exception is TException)
     {
         result = new ExceptionHandlingRetryResult(
             exception: exceptionInformation.Exception,
             isTransient: _isTransient,
             retryDelay: _retryDelay,
             maxRetryCount: _maxRetryCount);
         return(true);
     }
     result = new ExceptionHandlingThrowResult();
     return(false);
 }
 public bool TryHandleException(ExceptionInformation exceptionInformation, OperationRetrySettings retrySettings, out ExceptionHandlingResult result)
 {
     if (exceptionInformation.Exception is FabricCannotConnectException)
     {
         // <param name="isTransient">
         // Indicates if this is a transient retriable exception.
         // Transient retriable exceptions are those where the communication channel from client
         // to service still exists.
         // Non transient retriable exceptions are those where we need to re-resolve the service endpoint
         // before we retry.
         // </param>
         result = new ExceptionHandlingRetryResult(exceptionInformation.Exception, false, retrySettings, retrySettings.DefaultMaxRetryCount);
         return(true);
     }
     result = null;
     return(false);
 }
示例#19
0
        bool IExceptionHandler.TryHandleException(ExceptionInformation exceptionInformation, OperationRetrySettings retrySettings, out ExceptionHandlingResult result)
        {
            if (exceptionInformation.Exception is TimeoutException ||
                exceptionInformation.Exception is ConnectionFailedException ||
                exceptionInformation.Exception is OperationCanceledException)
            {
                result = new ExceptionHandlingRetryResult(exceptionInformation.Exception, false, retrySettings, 1);
                return(true);
            }

            else if (exceptionInformation.Exception is ProcessingException)
            {
                result = new ExceptionHandlingRetryResult(exceptionInformation.Exception, false, retrySettings, 0);
                return(true);
            }
            result = null;
            return(false);
        }
        /// <summary>
        /// Method that examines the exception and determines how that exception can be handled.
        /// </summary>
        /// <param name="exceptionInformation">Information about the exception</param>
        /// <param name="retrySettings">The operation retry preferences.</param>
        /// <param name="result">Result of the exception handling</param>
        /// <returns>true if the exception is handled, false otherwise</returns>
        bool IExceptionHandler.TryHandleException(
            ExceptionInformation exceptionInformation,
            OperationRetrySettings retrySettings,
            out ExceptionHandlingResult result)
        {
            var e = exceptionInformation.Exception;

            if (e is ActorConcurrencyLockTimeoutException)
            {
                if (ActorLogicalCallContext.IsPresent())
                {
                    result = new ExceptionHandlingThrowResult()
                    {
                        ExceptionToThrow = e
                    };
                    return(true);
                }

                result = new ExceptionHandlingRetryResult(
                    e,
                    true,
                    retrySettings,
                    retrySettings.DefaultMaxRetryCount);
                return(true);
            }

            // The messaging layer may deliver duplicate messages during the connection failures.
            //E.g when client connection is disconnected but service is still processing the message. We retry on client connection failures.
            //This results to service receiving duplicate message.
            //And Actor Reentrancy throws DuplicateMessageException exception when it sees a duplicate Message (message with same callContext).
            if (e is DuplicateMessageException)
            {
                result = new ExceptionHandlingRetryResult(
                    e,
                    true,
                    retrySettings,
                    int.MaxValue);

                return(true);
            }

            result = null;
            return(false);
        }
        public bool TryHandleException(ExceptionInformation exceptionInformation, OperationRetrySettings retrySettings, out ExceptionHandlingResult result)
        {
            _context.WriteEvent($"HttpExceptionHandler::TryHandleException: Encountered Exception {exceptionInformation.Exception}");

            if (exceptionInformation.Exception is TimeoutException)
            {
                result = new ExceptionHandlingRetryResult(exceptionInformation.Exception, false, retrySettings, retrySettings.DefaultMaxRetryCount);
                return(true);
            }
            else if (exceptionInformation.Exception is ProtocolViolationException)
            {
                result = new ExceptionHandlingThrowResult();
                return(true);
            }
            else if (exceptionInformation.Exception is SocketException)
            {
                result = new ExceptionHandlingRetryResult(exceptionInformation.Exception, false, retrySettings, retrySettings.DefaultMaxRetryCount);
                return(true);
            }

            HttpRequestException httpException = exceptionInformation.Exception as HttpRequestException;

            if (httpException != null)
            {
                _context.WriteEvent($"HttpExceptionHandler::TryHandleException: HttpRequestException {httpException}");

                result = null;
                return(false);
            }

            WebException we = exceptionInformation.Exception as WebException;

            if (we == null)
            {
                we = exceptionInformation.Exception.InnerException as WebException;
            }

            if (we != null)
            {
                _context.WriteEvent($"HttpExceptionHandler::TryHandleException: WebException {we}");

                HttpWebResponse errorResponse = we.Response as HttpWebResponse;

                if (we.Status == WebExceptionStatus.ProtocolError)
                {
                    _context.WriteEvent($"HttpExceptionHandler::TryHandleException: HttpWebResponse {errorResponse}");
                    _context.WriteEvent($"HttpExceptionHandler::TryHandleException: HttpWebResponse Status Code {errorResponse.StatusCode} Decription = {errorResponse.StatusDescription}");

                    result = null;
                    return(false);
                }

                if (we.Status == WebExceptionStatus.Timeout ||
                    we.Status == WebExceptionStatus.RequestCanceled ||
                    we.Status == WebExceptionStatus.ConnectionClosed ||
                    we.Status == WebExceptionStatus.ConnectFailure)
                {
                    result = new ExceptionHandlingRetryResult(exceptionInformation.Exception, false, retrySettings, retrySettings.DefaultMaxRetryCount);
                    return(true);
                }
            }

            result = null;
            return(false);
        }
示例#22
0
        public bool TryHandleException(ExceptionInformation exceptionInformation, OperationRetrySettings retrySettings,
                                       out ExceptionHandlingResult result)
        {
            if (exceptionInformation.Exception is TimeoutException)
            {
                result =
                    new ExceptionHandlingRetryResult(
                        exceptionInformation.Exception,
                        false,
                        retrySettings,
                        retrySettings.DefaultMaxRetryCount);

                return(true);
            }

            if (exceptionInformation.Exception is SocketException)
            {
                result =
                    new ExceptionHandlingRetryResult(
                        exceptionInformation.Exception,
                        false,
                        retrySettings,
                        retrySettings.DefaultMaxRetryCount);

                return(true);
            }

            if (exceptionInformation.Exception is ProtocolViolationException)
            {
                result = new ExceptionHandlingThrowResult();
                return(true);
            }

            var we = exceptionInformation.Exception.InnerException as WebException ??
                     exceptionInformation.Exception.InnerException as WebException;

            if (we != null)
            {
                var errorResponse = we.Response as HttpWebResponse;

                if (we.Status == WebExceptionStatus.ProtocolError)
                {
                    if (errorResponse != null && errorResponse.StatusCode == HttpStatusCode.NotFound)
                    {
                        result =
                            new ExceptionHandlingRetryResult(
                                exceptionInformation.Exception,
                                false,
                                retrySettings,
                                retrySettings.DefaultMaxRetryCount);

                        return(true);
                    }

                    if (errorResponse != null && errorResponse.StatusCode == HttpStatusCode.InternalServerError)
                    {
                        result =
                            new ExceptionHandlingRetryResult(
                                exceptionInformation.Exception,
                                true,
                                retrySettings,
                                retrySettings.DefaultMaxRetryCount);

                        return(true);
                    }
                }

                if (we.Status == WebExceptionStatus.Timeout ||
                    we.Status == WebExceptionStatus.RequestCanceled ||
                    we.Status == WebExceptionStatus.ConnectionClosed ||
                    we.Status == WebExceptionStatus.ConnectFailure)
                {
                    result =
                        new ExceptionHandlingRetryResult(
                            exceptionInformation.Exception,
                            false,
                            retrySettings,
                            retrySettings.DefaultMaxRetryCount);

                    return(true);
                }
            }

            result = null;
            return(false);
        }
        /// <summary>
        /// Method that examines the exception and determines how that exception can be handled.
        /// </summary>
        /// <param name="exceptionInformation">Information about the exception</param>
        /// <param name="retrySettings">The operation retry preferences.</param>
        /// <param name="result">Result of the exception handling</param>
        /// <returns>true if the exception is handled, false otherwise</returns>
        bool IExceptionHandler.TryHandleException(
            ExceptionInformation exceptionInformation,
            OperationRetrySettings retrySettings,
            out ExceptionHandlingResult result)
        {
            var e = exceptionInformation.Exception;

            // retry with resolve - these exceptions indicate a possible fail over
            if ((e is EndpointNotFoundException) ||
                (e is CommunicationObjectAbortedException) ||
                (e is CommunicationObjectFaultedException) ||
                (e is ObjectDisposedException) ||
                (e is ChannelTerminatedException))
            {
                result = new ExceptionHandlingRetryResult(
                    e,
                    false,
                    retrySettings,
                    int.MaxValue);
                return(true);
            }


            // retry on timeout and service busy exceptions
            if ((e is TimeoutException) ||
                (e is ServerTooBusyException))
            {
                result = new ExceptionHandlingRetryResult(
                    e,
                    true,
                    retrySettings,
                    int.MaxValue);
                return(true);
            }


            // Derived types of Communication Exception that are not retriable.
            if ((e is ActionNotSupportedException) ||
                (e is AddressAccessDeniedException))
            {
                result = new ExceptionHandlingThrowResult()
                {
                    ExceptionToThrow = e
                };
                return(true);
            }

            // Security related derived types of Communication Exception that are not retriable
            if (e is SecurityAccessDeniedException)
            {
                result = new ExceptionHandlingThrowResult()
                {
                    ExceptionToThrow = e
                };
                return(true);
            }


            var faultException = e as FaultException;

            if (faultException != null)
            {
                if (faultException.Code.Name == WcfRemoteExceptionInformation.FaultCodeName)
                {
                    var actualException = WcfRemoteExceptionInformation.ToException(faultException.Reason.ToString());

                    if (faultException.Code.SubCode.Name == WcfRemoteExceptionInformation.FaultSubCodeRetryName)
                    {
                        result = new ExceptionHandlingRetryResult(
                            actualException,
                            false,
                            retrySettings,
                            int.MaxValue);
                        return(true);
                    }
                }
            }

            // retry on all communication exceptions, including the protocol exceptions for default max retry
            if ((faultException == null) && (e is CommunicationException))
            {
                result = new ExceptionHandlingRetryResult(
                    e,
                    false,
                    retrySettings,
                    retrySettings.DefaultMaxRetryCount);
                return(true);
            }

            result = null;
            return(false);
        }
        public bool TryHandleException(ExceptionInformation exceptionInformation, OperationRetrySettings retrySettings, out ExceptionHandlingResult result)
        {
            Exception e = exceptionInformation.Exception;

            Logger.Debug("OnHandleException {0}", e);

            if (e is TimeoutException)
            {
                result = new ExceptionHandlingRetryResult(e, false, retrySettings, retrySettings.DefaultMaxRetryCount);
                return(true);
            }

            if (e is ProtocolViolationException)
            {
                result = new ExceptionHandlingRetryResult(e, false, retrySettings, retrySettings.DefaultMaxRetryCount);
                return(true);
            }

            if (e is HttpRequestException)
            {
                HttpRequestException he = (HttpRequestException)e;

                // this should not happen, but let's do a sanity check
                if (null == he.InnerException)
                {
                    result = new ExceptionHandlingRetryResult(e, false, retrySettings, retrySettings.DefaultMaxRetryCount);
                    return(true);
                }

                e = he.InnerException;
            }

            if (e is WebException)
            {
                WebException    we            = (WebException)e;
                HttpWebResponse errorResponse = we.Response as HttpWebResponse;

                if (we.Status == WebExceptionStatus.ProtocolError)
                {
                    if (errorResponse.StatusCode == HttpStatusCode.NotFound)
                    {
                        // This could either mean we requested an endpoint that does not exist in the service API (a user error)
                        // or the address that was resolved by fabric client is stale (transient runtime error) in which we should re-resolve.
                        result = new ExceptionHandlingRetryResult(e, false, retrySettings, retrySettings.DefaultMaxRetryCount);
                        return(true);
                    }

                    if (errorResponse.StatusCode == HttpStatusCode.InternalServerError)
                    {
                        // The address is correct, but the server processing failed.
                        // This could be due to conflicts when writing the word to the dictionary.
                        // Retry the operation without re-resolving the address.
                        result = new ExceptionHandlingRetryResult(e, true, retrySettings, retrySettings.DefaultMaxRetryCount);
                        return(true);
                    }
                }

                if (we.Status == WebExceptionStatus.Timeout ||
                    we.Status == WebExceptionStatus.RequestCanceled ||
                    we.Status == WebExceptionStatus.ConnectionClosed ||
                    we.Status == WebExceptionStatus.ConnectFailure)
                {
                    result = new ExceptionHandlingRetryResult(e, false, retrySettings, retrySettings.DefaultMaxRetryCount);
                    return(true);
                }
            }

            result = new ExceptionHandlingRetryResult(e, false, retrySettings, retrySettings.DefaultMaxRetryCount);
            return(true);
        }
        public bool TryHandleException(ExceptionInformation exceptionInformation, OperationRetrySettings retrySettings, out ExceptionHandlingResult result)
        {
            if (exceptionInformation == null)
            {
                throw new ArgumentNullException(nameof(exceptionInformation));
            }

            var ex = exceptionInformation.Exception;

            // errors where we didn't get a response from the service.

            if (ex is TaskCanceledException || ex is TimeoutException)
            {
                _logger.RetryingServiceCall(ex.GetType().Name);

                return(CreateExceptionHandlingRetryResult(false, ex, out result));
            }

            if (ex is ProtocolViolationException)
            {
                _logger.RetryingServiceCall("ProtocolViolationException", null, ex);

                return(CreateExceptionHandlingRetryResult(false, ex, out result));
            }

            var webEx = ex as WebException ?? ex.InnerException as WebException;

            if (webEx != null)
            {
                if (webEx.Status == WebExceptionStatus.Timeout ||
                    webEx.Status == WebExceptionStatus.RequestCanceled ||
                    webEx.Status == WebExceptionStatus.ConnectionClosed ||
                    webEx.Status == WebExceptionStatus.ConnectFailure)
                {
                    _logger.RetryingServiceCall("WebExceptionStatus " + webEx.Status, null, ex);

                    return(CreateExceptionHandlingRetryResult(false, webEx, out result));
                }
            }

            // we got a response from the service - let's try to get the StatusCode to see if we should retry.

            if (_options.RetryHttpStatusCodeErrors)
            {
                HttpStatusCode?     httpStatusCode  = null;
                HttpWebResponse     webResponse     = null;
                HttpResponseMessage responseMessage = null;

                var httpEx = ex as HttpResponseException;
                if (httpEx != null)
                {
                    responseMessage = httpEx.Response;
                    httpStatusCode  = httpEx.Response.StatusCode;
                }
                else if (webEx != null)
                {
                    webResponse    = webEx.Response as HttpWebResponse;
                    httpStatusCode = webResponse?.StatusCode;
                }

                if (httpStatusCode.HasValue)
                {
                    if (httpStatusCode == HttpStatusCode.NotFound)
                    {
                        // This could either mean we requested an endpoint that does not exist in the service API (a user error)
                        // or the address that was resolved by fabric client is stale (transient runtime error) in which we should re-resolve.

                        _logger.RetryingServiceCall("HTTP 404");

                        result = new ExceptionHandlingRetryResult(
                            exceptionId: "HTTP 404",
                            isTransient: false,
                            retryDelay: TimeSpan.FromMilliseconds(100),
                            maxRetryCount: 2);

                        return(true);
                    }

                    if ((int)httpStatusCode >= 500 && (int)httpStatusCode < 600)
                    {
                        // The address is correct, but the server processing failed.
                        // Retry the operation without re-resolving the address.

                        // we want to log the response in case it contains useful information (e.g. in dev environments)
                        string errorResponse = null;
                        if (webResponse != null)
                        {
                            using (StreamReader streamReader = new StreamReader(webResponse.GetResponseStream()))
                            {
                                errorResponse = streamReader.ReadToEnd();
                            }
                        }
                        else if (responseMessage != null)
                        {
                            // not sure if just calling ReadAsStringAsync().Result can result in a deadlock.
                            // so better safe than sorry...
                            // http://stackoverflow.com/questions/22628087/calling-async-method-synchronously
                            // AsyncEx library would be good but I don't want to take a dependency on that just for this one case.
                            errorResponse = Task.Run(() => responseMessage.Content.ReadAsStringAsync()).Result;
                        }

                        _logger.RetryingServiceCall($"HTTP {(int) httpStatusCode}", errorResponse);

                        return(CreateExceptionHandlingRetryResult(true, ex, out result));
                    }
                }
            }

            _logger.ServiceCallFailed(ex);

            result = null;
            return(false);
        }
        public bool TryHandleException(ExceptionInformation exceptionInformation, OperationRetrySettings retrySettings, out ExceptionHandlingResult result)
        {
            if (exceptionInformation == null)
            {
                throw new ArgumentNullException(nameof(exceptionInformation));
            }

            var ex = exceptionInformation.Exception;

            // errors where we didn't get a response from the service.

            if (ex is TaskCanceledException || ex is TimeoutException)
            {
                _logger.RetryingServiceCall(ex.GetType().Name);

                return CreateExceptionHandlingRetryResult(false, ex, out result);
            }

            if (ex is ProtocolViolationException)
            {
                _logger.RetryingServiceCall("ProtocolViolationException", null, ex);

                return CreateExceptionHandlingRetryResult(false, ex, out result);
            }

            var webEx = ex as WebException ?? ex.InnerException as WebException;
            if (webEx != null)
            {
                if (webEx.Status == WebExceptionStatus.Timeout ||
                    webEx.Status == WebExceptionStatus.RequestCanceled ||
                    webEx.Status == WebExceptionStatus.ConnectionClosed ||
                    webEx.Status == WebExceptionStatus.ConnectFailure)
                {
                    _logger.RetryingServiceCall("WebExceptionStatus " + webEx.Status, null, ex);

                    return CreateExceptionHandlingRetryResult(false, webEx, out result);
                }
            }

            // we got a response from the service - let's try to get the StatusCode to see if we should retry.

            if (_options.RetryHttpStatusCodeErrors)
            {
                HttpStatusCode? httpStatusCode = null;
                HttpWebResponse webResponse = null;
                HttpResponseMessage responseMessage = null;

                var httpEx = ex as HttpResponseException;
                if (httpEx != null)
                {
                    responseMessage = httpEx.Response;
                    httpStatusCode = httpEx.Response.StatusCode;
                }
                else if (webEx != null)
                {
                    webResponse = webEx.Response as HttpWebResponse;
                    httpStatusCode = webResponse?.StatusCode;
                }

                if (httpStatusCode.HasValue)
                {
                    if (httpStatusCode == HttpStatusCode.NotFound)
                    {
                        // This could either mean we requested an endpoint that does not exist in the service API (a user error)
                        // or the address that was resolved by fabric client is stale (transient runtime error) in which we should re-resolve.

                        _logger.RetryingServiceCall("HTTP 404");

                        result = new ExceptionHandlingRetryResult(
                            exceptionId: "HTTP 404",
                            isTransient: false,
                            retryDelay: TimeSpan.FromMilliseconds(100),
                            maxRetryCount: 2);

                        return true;
                    }

                    if ((int)httpStatusCode >= 500 && (int)httpStatusCode < 600)
                    {
                        // The address is correct, but the server processing failed.
                        // Retry the operation without re-resolving the address.

                        // we want to log the response in case it contains useful information (e.g. in dev environments)
                        string errorResponse = null;
                        if (webResponse != null)
                        {
                            using (StreamReader streamReader = new StreamReader(webResponse.GetResponseStream()))
                            {
                                errorResponse = streamReader.ReadToEnd();
                            }
                        }
                        else if (responseMessage != null)
                        {
                            // not sure if just calling ReadAsStringAsync().Result can result in a deadlock.
                            // so better safe than sorry...
                            // http://stackoverflow.com/questions/22628087/calling-async-method-synchronously
                            // AsyncEx library would be good but I don't want to take a dependency on that just for this one case.
                            errorResponse = Task.Run(() => responseMessage.Content.ReadAsStringAsync()).Result;
                        }

                        _logger.RetryingServiceCall($"HTTP {(int) httpStatusCode}", errorResponse);

                        return CreateExceptionHandlingRetryResult(true, ex, out result);
                    }
                }
            }

            _logger.ServiceCallFailed(ex);

            result = null;
            return false;
        }
        private bool CreateExceptionHandlingRetryResult(bool isTransient, Exception ex, out ExceptionHandlingResult result)
        {
            result = new ExceptionHandlingRetryResult(
                exceptionId: ex.GetType().Name,
                isTransient: isTransient,
                retryDelay: TimeSpan.FromMilliseconds(_rand.NextDouble()*_options.MaxRetryBackoffInterval.TotalMilliseconds),
                maxRetryCount: _options.MaxRetryCount);

            return true;
        }
        public bool TryHandleException(ExceptionInformation exceptionInformation, OperationRetrySettings retrySettings, out ExceptionHandlingResult result)
        {
            Exception e = exceptionInformation.Exception;

            Logger.Debug("OnHandleException {0}", e);

            if (e is TimeoutException)
            {
                result = new ExceptionHandlingRetryResult(e, false, retrySettings, retrySettings.DefaultMaxRetryCount);
                return true;
            }

            if (e is ProtocolViolationException)
            {
                result = new ExceptionHandlingRetryResult(e, false, retrySettings, retrySettings.DefaultMaxRetryCount);
                return true;
            }

            if (e is HttpRequestException)
            {
                HttpRequestException he = (HttpRequestException) e;

                // this should not happen, but let's do a sanity check
                if (null == he.InnerException)
                {
                    result = new ExceptionHandlingRetryResult(e, false, retrySettings, retrySettings.DefaultMaxRetryCount);
                    return true;
                }

                e = he.InnerException;
            }

            if (e is WebException)
            {
                WebException we = (WebException) e;
                HttpWebResponse errorResponse = we.Response as HttpWebResponse;

                if (we.Status == WebExceptionStatus.ProtocolError)
                {
                    if (errorResponse.StatusCode == HttpStatusCode.NotFound)
                    {
                        // This could either mean we requested an endpoint that does not exist in the service API (a user error)
                        // or the address that was resolved by fabric client is stale (transient runtime error) in which we should re-resolve.
                        result = new ExceptionHandlingRetryResult(e, false, retrySettings, retrySettings.DefaultMaxRetryCount);
                        return true;
                    }

                    if (errorResponse.StatusCode == HttpStatusCode.InternalServerError)
                    {
                        // The address is correct, but the server processing failed.
                        // This could be due to conflicts when writing the word to the dictionary.
                        // Retry the operation without re-resolving the address.
                        result = new ExceptionHandlingRetryResult(e, true, retrySettings, retrySettings.DefaultMaxRetryCount);
                        return true;
                    }
                }

                if (we.Status == WebExceptionStatus.Timeout ||
                    we.Status == WebExceptionStatus.RequestCanceled ||
                    we.Status == WebExceptionStatus.ConnectionClosed ||
                    we.Status == WebExceptionStatus.ConnectFailure)
                {
                    result = new ExceptionHandlingRetryResult(e, false, retrySettings, retrySettings.DefaultMaxRetryCount);
                    return true;
                }
            }

            result = new ExceptionHandlingRetryResult(e, false, retrySettings, retrySettings.DefaultMaxRetryCount);
            return true;
        }
 private bool RetryResult(ExceptionInformation exceptionInformation, out ExceptionHandlingResult result)
 {
     result = new ExceptionHandlingRetryResult(exceptionInformation.Exception, TransientException, this.operationRetrySettings, this.operationRetrySettings.DefaultMaxRetryCount);
     return(KnownException);
 }
示例#30
0
 public bool TryHandleException(ExceptionInformation exceptionInformation, OperationRetrySettings retrySettings, out ExceptionHandlingResult result)
 {
     result = new ExceptionHandlingRetryResult(exceptionInformation.Exception, false, retrySettings, retrySettings.DefaultMaxRetryCount);
     //// Log Error Here.
     return(true);
 }