protected override bool CheckIsTransient(Exception ex) { bool returnValue = false; try { var dataServiceException = ex.FindInnerException<DataServiceRequestException>(); if ((dataServiceException != null) && (dataServiceException.Response != null)) { if (dataServiceException.Response.IsBatchResponse) { returnValue = CommonRetryableWebExceptions.Any(s => (int)s == dataServiceException.Response.BatchStatusCode); } else { // If this isn't a batch response we have to check the StatusCode on the Response object itself var responses = dataServiceException.Response.ToList(); if (responses.Count == 1) { returnValue = CommonRetryableWebExceptions.Any(s => (int)s == responses[0].StatusCode); } } } } catch (Exception) { // we don't want to hide the original exception with any errors we might generate here // so just swallow the exception and don't retry returnValue = false; } return returnValue; }
protected override bool CheckIsTransient(Exception ex) { var webException = ex.FindInnerException<WebException>(); if (webException != null && CommonRetryableWebExceptions.Contains(webException.Status)) { return true; } if (ex.FindInnerException<TimeoutException>() != null) { return true; } return false; }
protected override bool CheckIsTransient(Exception ex) { var dataServiceException = ex.FindInnerException<DataServiceQueryException>(); if (dataServiceException == null) { return false; } return CommonRetryableWebExceptions.Any(s => dataServiceException.Response != null && (int)s == dataServiceException.Response.StatusCode); }
protected override bool CheckIsTransient(Exception ex) { var dataServiceException = ex.FindInnerException<DataServiceRequestException>(); if (dataServiceException == null) { return false; } if (dataServiceException.Response.IsBatchResponse && CommonRetryableWebExceptions.Any(s => (int)s == dataServiceException.Response.BatchStatusCode)) { return true; } var responses = dataServiceException.Response.ToList(); //If we have responses with retryable status codes we should retry return responses.Any(r => CommonRetryableWebExceptions.Any(s => (int)s == r.StatusCode)); }
protected override bool CheckIsTransient(Exception ex) { if (IsRetriableWebException(ex, operationIdempotentOnRetry: true, retryOnUnauthorizedErrors: true)) { return true; } DataServiceRequestException dataServiceException = ex as DataServiceRequestException; if (dataServiceException != null) { if (IsErrorStringMatch(GetErrorCode(dataServiceException), StorageErrorCodeStrings.InternalError, StorageErrorCodeStrings.ServerBusy, StorageErrorCodeStrings.OperationTimedOut, TableErrorCodeStrings.TableServerOutOfMemory)) { return true; } } DataServiceQueryException dataServiceQueryException = ex as DataServiceQueryException; if (dataServiceQueryException != null) { if (IsErrorStringMatch(GetErrorCode(dataServiceQueryException), StorageErrorCodeStrings.InternalError, StorageErrorCodeStrings.ServerBusy, StorageErrorCodeStrings.OperationTimedOut, TableErrorCodeStrings.TableServerOutOfMemory)) { return true; } } DataServiceClientException dataServiceClientException = ex.FindInnerException<DataServiceClientException>(); if (dataServiceClientException != null) { if (IsRetriableHttpStatusCode(dataServiceClientException.StatusCode, operationIdempotentOnRetry:true, retryOnUnauthorizedErrors:true)) { return true; } if (IsErrorStringMatch(dataServiceClientException.Message, StorageErrorCodeStrings.InternalError, StorageErrorCodeStrings.ServerBusy, StorageErrorCodeStrings.OperationTimedOut, TableErrorCodeStrings.TableServerOutOfMemory)) { return true; } } var serverException = ex as StorageException; if (serverException != null) { if (IsErrorStringMatch(serverException, StorageErrorCodeStrings.InternalError, StorageErrorCodeStrings.ServerBusy, StorageErrorCodeStrings.OperationTimedOut, TableErrorCodeStrings.TableServerOutOfMemory)) { return true; } } if (IsTimeoutException(ex)) { return true; } if (IsSocketException(ex)) { return true; } if ((ex.FindInnerException<IOException>() != null) && !(ex is FileLoadException)) { return true; } return false; }
protected bool IsRetriableDataServiceException(Exception ex, bool operationIdempotentOnRetry, bool retryOnUnauthorizedErrors) { try { var transportException = ex.FindInnerException<DataServiceTransportException>(); if (transportException != null) { if (transportException.Response == null) { // If we don't have a response object to look at then we don't really know what happened on the server. // Thus if the operation is Idempotent, we will go ahead and retry because even if the first operation // succeeded on the server redoing the operation won't change the final result. If the operation is // not idempotent, we won't retry since we don't have any details on the error. return operationIdempotentOnRetry; } else if (IsRetriableHttpStatusCode(transportException.Response.StatusCode, operationIdempotentOnRetry, retryOnUnauthorizedErrors)) { return true; } } var requestException = ex.FindInnerException<DataServiceRequestException>(); if (requestException != null) { if (requestException.Response == null) { // If we don't have a response object to look at then we don't really know what happened on the server. // Thus if the operation is Idempotent, we will go ahead and retry because even if the first operation // succeeded on the server redoing the operation won't change the final result. If the operation is // not idempotent, we won't retry since we don't have any details on the error. return operationIdempotentOnRetry; } else if (requestException.Response.IsBatchResponse) { if (IsRetriableHttpStatusCode(requestException.Response.BatchStatusCode, operationIdempotentOnRetry, retryOnUnauthorizedErrors)) { return true; } } else { // If this isn't a batch response we have to check the StatusCode on the Response object itself var responses = requestException.Response.ToList(); if ((responses.Count == 1) && IsRetriableHttpStatusCode(responses[0].StatusCode, operationIdempotentOnRetry, retryOnUnauthorizedErrors)) { return true; } } } var queryException = ex.FindInnerException<DataServiceQueryException>(); if (queryException != null) { if (queryException.Response == null) { // If we don't have a response object to look at then we don't really know what happened on the server. // Thus if the operation is Idempotent, we will go ahead and retry because even if the first operation // succeeded on the server redoing the operation won't change the final result. If the operation is // not idempotent, we won't retry since we don't have any details on the error. return operationIdempotentOnRetry; } else if (IsRetriableHttpStatusCode(queryException.Response.StatusCode, operationIdempotentOnRetry, retryOnUnauthorizedErrors)) { return true; } } var clientException = ex.FindInnerException<DataServiceClientException>(); if (clientException != null) { if (IsRetriableHttpStatusCode(clientException.StatusCode, operationIdempotentOnRetry, retryOnUnauthorizedErrors)) { return true; } } } catch (Exception) { // do nothing, just return false below } return false; }
protected bool IsTimeoutException(Exception ex) { return (ex is TimeoutException || (ex.FindInnerException<TimeoutException>() != null)); }
protected bool IsSocketException(Exception ex) { return (ex is SocketException || (ex.FindInnerException<SocketException>() != null)); }
protected bool IsRetriableWebException(Exception ex, bool operationIdempotentOnRetry, bool retryOnUnauthorizedErrors) { try { var webException = ex.FindInnerException<WebException>(); if (webException != null) { if (CommonRetryableWebExceptions.Contains(webException.Status)) { return true; } else if (webException.Status == WebExceptionStatus.ProtocolError) { // The response received from the server was complete but indicated a protocol-level error. // Decide if the HTTP protocol error is retriable or not. var response = webException.Response as HttpWebResponse; if (response == null || IsRetriableHttpStatusCode(response.StatusCode, operationIdempotentOnRetry, retryOnUnauthorizedErrors)) { return true; } } else if (operationIdempotentOnRetry) { if (RetryableWebExceptionsForIdempotentOperations.Contains(webException.Status)) { return true; } } } } catch(Exception) { // do nothing, just return false below } return false; }
protected bool IsIOException(Exception ex) { return (ex is IOException || (ex.FindInnerException<IOException>() != null)); }