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