예제 #1
0
        private bool HandleReportedException(
            ExceptionInformation exceptionInformation,
            OperationRetrySettings retrySettings,
            out ExceptionHandlingResult result)
        {
            var aggregateException = exceptionInformation.Exception as AggregateException;

            if (aggregateException == null)
            {
                return(this.TryHandleException(
                           exceptionInformation,
                           retrySettings,
                           out result));
            }

            foreach (var innerException in aggregateException.Flatten().InnerExceptions)
            {
                if (this.TryHandleException(
                        new ExceptionInformation(innerException, exceptionInformation.TargetReplica),
                        retrySettings,
                        out result))
                {
                    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);
        }
예제 #3
0
        public void ClientExceptionTest()
        {
            LoggingProvider <ClientLoggingHandler> .Log("Test", Category.Common);

            IOException e = new IOException("File Not Exist");


            try
            {
                string result = string.Empty;
                string actual = string.Empty;

                ClientExceptionHandlerProvider.RepaireExceptionPolicies();

                ExceptionHandlingResult exceptionHandlingResult = ExceptionManager.Instance.HandleException(e, "Policy1");

                result = exceptionHandlingResult.Message;
                actual = "The process cannot access the file because it is being used by another process.";


                Assert.IsTrue(result == actual, "Exception error");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
            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);
            }
예제 #5
0
            static async Task RewriteRequestToPath(
                HttpContext httpContext,
                string pattern,
                object?routeValues)
            {
                var routePatternFormatter = httpContext.RequestServices.GetRequiredService <IRoutePatternFormatter>();
                var feature = httpContext.Features.Get <IExceptionMappingFeature>();

                var path = routePatternFormatter.Format(httpContext, RoutePatternFactory.Parse(pattern), routeValues);

                if (path == null)
                {
                    // Unable to format route pattern, rethrow the exception
                    var exceptionHandlingContext = httpContext.Features.Get <IExceptionMappingContextFeature>().Context !;
                    exceptionHandlingContext.Result = ExceptionHandlingResult.Rethrow(exceptionHandlingContext.Exception);
                    return;
                }

                httpContext.Request.Path = path;
                try
                {
                    await feature.RequestPipeline(httpContext);
                }
                finally
                {
                    httpContext.Request.Path = feature.RequestPath;
                }
            }
 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;
 }
        private static void AssertIsTransientRetryResult(ExceptionHandlingResult exceptionHandlingResult, bool isKnownException, bool resolvesAddress)
        {
            var exceptionHandlingRetryResult = exceptionHandlingResult as ExceptionHandlingRetryResult;

            Assert.That(isKnownException, Is.True);
            Assert.That(exceptionHandlingRetryResult, Is.Not.Null);
            Assert.That(exceptionHandlingRetryResult.IsTransient, Is.EqualTo(!resolvesAddress)); // This is the property that tells the ServicePartitionClient to re-resolve the address and try again
        }
        protected override async Task OnExecutionAsync(ExceptionHandlingContext context, HttpContext httpContext)
        {
            await _requestHandler(httpContext);

            if (!context.Result.IsHandled)
            {
                context.Result = ExceptionHandlingResult.Handled();
            }
        }
        protected override ValueTask <ExceptionHandlingResult> HandleExceptionAsync(
            ExceptionHandlingContext context)
        {
            if (Options.Run)
            {
                return(ExceptionHandlingResult.Return(_result));
            }

            return(default);
        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);
        }
        public void when_handling_a_webexception_with_a_serviceunavailable_http_status_code_then_a_transient_retry_result_that_does_not_resolve_the_address_is_returned()
        {
            // Arrange
            ExceptionHandlingResult exceptionHandlingResult = null;
            var exceptionInformation = GetExceptionInformationForWebExceptionWithStatusCode(HttpStatusCode.ServiceUnavailable);

            // Act
            var isKnownException = this.httpExceptionHandler.TryHandleException(exceptionInformation, operationRetrySettings, out exceptionHandlingResult);

            // Assert
            AssertIsTransientRetryResultThatDoesNotResolveTheAddress(exceptionHandlingResult, isKnownException);
        }
        public void when_handling_a_socketexception_then_a_transient_retry_result_that_resolves_the_address_is_returned()
        {
            // Arrange
            ExceptionHandlingResult exceptionHandlingResult = null;
            var exceptionInformation = new ExceptionInformation(new SocketException());

            // Act
            var isKnownException = this.httpExceptionHandler.TryHandleException(exceptionInformation, operationRetrySettings, out exceptionHandlingResult);

            // Assert
            AssertIsTransientRetryResultThatResolvesTheAddress(exceptionHandlingResult, isKnownException);
        }
        public void when_handling_a_webexception_with_retryable_status_then_a_non_transient_retry_result_that_does_not_resolve_the_address_is_returned(WebExceptionStatus webExceptionStatus)
        {
            // Arrange
            ExceptionHandlingResult exceptionHandlingResult = null;
            var exceptionInformation = new ExceptionInformation(new WebException(string.Empty, webExceptionStatus));

            // Act
            var isKnownException = this.httpExceptionHandler.TryHandleException(exceptionInformation, operationRetrySettings, out exceptionHandlingResult);

            // Assert
            AssertIsTransientRetryResultThatDoesNotResolveTheAddress(exceptionHandlingResult, isKnownException);
        }
        public void when_handling_a_webexception_with_a_gatewaytimeout_http_status_code_then_a_transient_retry_result_that_resolves_the_address_is_returned()
        {
            // Arrange
            ExceptionHandlingResult exceptionHandlingResult = null;
            var exceptionInformation = GetExceptionInformationForWebExceptionWithStatusCode(HttpStatusCode.GatewayTimeout);

            // Act
            var isKnownException = this.httpExceptionHandler.TryHandleException(exceptionInformation, operationRetrySettings, out exceptionHandlingResult);

            // Assert
            AssertIsTransientRetryResultThatResolvesTheAddress(exceptionHandlingResult, isKnownException);
        }
예제 #16
0
        public async Task ShouldReturnNullIfSuppressDefault()
        {
            var mapper = MapperTestHelper.CreateMapper(opt =>
                                                       opt.FallbackExceptionHandler = async ctx =>
            {
                await Task.Yield();
                ctx.Result = ExceptionHandlingResult.Return(null);
            });

            var result = await mapper.MapExceptionAsync(new Exception());

            Assert.Null(result);
        }
        public void when_handling_a_webexception_with_a_5xx_non_transient_and_non_retryable_http_status_code_then_no_retry_result_is_returned(HttpStatusCode httpStatusCode)
        {
            // Arrange
            ExceptionHandlingResult exceptionHandlingResult = null;
            var exceptionInformation = GetExceptionInformationForWebExceptionWithStatusCode(httpStatusCode);

            // Act
            var isKnownException = this.httpExceptionHandler.TryHandleException(exceptionInformation, operationRetrySettings, out exceptionHandlingResult);

            // Assert
            Assert.That(isKnownException, Is.False);
            Assert.That(exceptionHandlingResult, Is.Null);
        }
        public void when_handling_a_non_retryable_exception_then_no_retry_result_is_returned()
        {
            // Arrange
            ExceptionHandlingResult exceptionHandlingResult = null;
            var exceptionInformation = new ExceptionInformation(new InvalidOperationException());

            // Act
            var isKnownException = this.httpExceptionHandler.TryHandleException(exceptionInformation, operationRetrySettings, out exceptionHandlingResult);

            // Assert
            Assert.That(isKnownException, Is.False);
            Assert.That(exceptionHandlingResult, Is.Null);
        }
예제 #19
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;
        }
        /// <summary>
        /// Excecute the command
        /// </summary>
        /// <param name="ex">Exception</param>
        /// <returns>ExceptionHandlingResult</returns>
        public override ExceptionHandlingResult Execute(InfrastructureException ex)
        {
            if (!ex.IsHandled)
            {
                return(DefaultHandle(ex));
            }

            else
            {
                ExceptionHandlingResult result = new ExceptionHandlingResult();
                result.Exception = ex;
                result.Handled   = true;
                return(result);
            }
        }
        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;
        }
예제 #22
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);
 }
 internal static bool HandleAggregateException(Exception exception, ExceptionHandlerDelegate exceptionHandler, out ExceptionHandlingResult result)
 {
     if (!(exception is AggregateException))
     {
         return exceptionHandler(exception, out result);
     }
     var ex = (AggregateException)exception;
     foreach (var current in ex.InnerExceptions)
     {
         if (HandleAggregateException(current, exceptionHandler, out result))
         {
             return true;
         }
     }
     result = null;
     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);
 }
            bool IExceptionHandler.TryHandleException(
                ExceptionInformation exceptionInformation,
                OperationRetrySettings retrySettings,
                out ExceptionHandlingResult result)
            {
                var fabricException = exceptionInformation.Exception as FabricException;

                if (fabricException != null)
                {
                    return(TryHandleFabricException(
                               fabricException,
                               retrySettings,
                               out result));
                }

                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);
        }
예제 #28
0
        protected override bool OnHandleException(Exception e, out ExceptionHandlingResult result)
        {
            if (e is TimeoutException)
            {
                return(this.CreateExceptionHandlingResult(false, out result));
            }
            else if (e is ProtocolViolationException)
            {
                return(this.CreateExceptionHandlingResult(false, out result));
            }
            else if (e is WebException)
            {
                WebException    we            = e 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.
                        return(this.CreateExceptionHandlingResult(false, out result));
                    }

                    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.
                        return(this.CreateExceptionHandlingResult(true, out result));
                    }
                }

                if (we.Status == WebExceptionStatus.Timeout ||
                    we.Status == WebExceptionStatus.RequestCanceled ||
                    we.Status == WebExceptionStatus.ConnectionClosed ||
                    we.Status == WebExceptionStatus.ConnectFailure)
                {
                    return(this.CreateExceptionHandlingResult(false, out result));
                }
            }

            return(base.OnHandleException(e, out result));
        }
예제 #29
0
        private bool TryHandleException(
            ExceptionInformation exceptionInformation,
            OperationRetrySettings retrySettings,
            out ExceptionHandlingResult result)
        {
            foreach (var handler in this.exceptionHandlers)
            {
                if (handler.TryHandleException(
                        exceptionInformation,
                        retrySettings,
                        out result))
                {
                    return(true);
                }
            }

            result = null;
            return(false);
        }
예제 #30
0
        public void ClientExceptionTest()
        {
            LoggingProvider <ClientLoggingHandler> .Log("Test", Category.Common);

            IOException e = new IOException("File Not Exist");


            try
            {
                ClientExceptionHandlerProvider.RepaireExceptionPolicies();

                ExceptionHandlingResult exceptionHandlingResult = ExceptionManager.Instance.HandleException(e, "Policy1");

                Assert.AreEqual(exceptionHandlingResult.Message, "The process cannot access the file because it is being used by another process.");
            }
            catch (Exception ex)
            {
            }
        }
        private bool HandleIfWebException(ExceptionInformation exceptionInformation, out ExceptionHandlingResult result)
        {
            result = null;

            WebException we = TryGetWebExceptionFrom(exceptionInformation);

            if (we == null)
            {
                return(false);
            }

            var errorResponse = we.Response as HttpWebResponse;

            if (we.Status == WebExceptionStatus.ProtocolError && errorResponse != null)
            {
                if (IsGatewayStatusCode(errorResponse.StatusCode))
                {
                    return(ResolveAddressAndRetryResult(exceptionInformation, out result));
                }

                if (errorResponse.StatusCode == HttpStatusCode.ServiceUnavailable)
                {
                    return(RetryResult(exceptionInformation, out result));
                }
            }

            if (IsTransientRetryableWebException(we))
            {
                return(ResolveAddressAndRetryResult(exceptionInformation, out result));
            }

            if (IsNonTransientRetryableWebException(we))
            {
                return(RetryResult(exceptionInformation, out result));
            }

            return(false);
        }
예제 #32
0
        /// <summary>
        /// Tries to handle the exception.
        /// </summary>
        /// <param name="exceptionInformation">
        /// The exception information.
        /// </param>
        /// <param name="retrySettings">
        /// The retry settings.
        /// </param>
        /// <param name="result">
        /// The result.
        /// </param>
        /// <returns>
        /// <b>true</b> if the exception was handled; otherwise, <b>false</b>.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// Either the exception information of the retry settings is null.
        /// </exception>
        public bool TryHandleException(
            ExceptionInformation exceptionInformation,
            OperationRetrySettings retrySettings,
            out ExceptionHandlingResult result)
        {
            if (exceptionInformation == null)
            {
                throw new ArgumentNullException("exceptionInformation");
            }

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

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

            return(true);
        }
예제 #33
0
        /// <summary>
        /// Excecute the command
        /// </summary>
        /// <param name="ex">Exception</param>
        /// <returns>ExceptionHandlingResult</returns>

        public override ExceptionHandlingResult Execute(ModelException ex)
        {
            if (!ex.IsHandled)
            {
                ExceptionHandlingResult result = new ExceptionHandlingResult();
                foreach (IExceptionHandlerCommand command in Commands.Values)
                {
                    ex.CustomMessage = citPOINT.eNeg.Infrastructure.Common.ExceptionsFriendlyMessages.ModelException;
                    result.Handled   = command.Execute(ex);
                    result.Exception = ex;
                    result.Message   = command.Message;
                }
                return(result);
            }

            else
            {
                ExceptionHandlingResult result = new ExceptionHandlingResult();
                result.Exception = ex;
                result.Handled   = true;
                return(result);
            }
        }
        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 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)
        {
            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;
        }
예제 #37
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 SocketException)
            {
                result = new ExceptionHandlingRetryResult(exceptionInformation.Exception, false, retrySettings, retrySettings.DefaultMaxRetryCount);
                return(true);
            }

            var we = exceptionInformation.Exception as WebException;

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

            if (we != null)
            {
                var 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.
                        // This could be due to conflicts when writing the word to the dictionary.
                        // 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);
        }
 bool IExceptionHandler.HandleException(Exception e, out ExceptionHandlingResult result)
 {
     var faultException = e as FaultException<RemoteExceptionInformation>;
     if (faultException == null)
     {
         result = null;
         return false;
     }
     Exception exception;
     if (!RemoteExceptionInformation.ToException(faultException.Detail, out exception))
     {
         throw new ArgumentException("failed to deserialize and get remote exception", nameof(e));
     }
     return ExceptionUtility.HandleAggregateException(exception, _owner.HandleRemoteException, out result);
 }