/// <summary> /// Returns whether a failed request should be retried according to the given request context. In the following /// circumstances, the request will fail directly without consulting this method: /// <ul> /// <li>if it has already reached the max retry limit, /// <li>if the request contains non-repeatable content, /// <li>if any RuntimeException or Error is thrown when executing the request. /// </ul> /// </summary> /// <param name="exception"> the exception from the failed request, represented as a BceClientException object. </param> /// <param name="retriesAttempted"> the number of times the current request has been attempted. </param> /// <returns> true if the failed request should be retried. </returns> protected virtual bool ShouldRetry(Exception exception, int retriesAttempted) { // Don't retry if stream can not seek. if (!CanRetry) { return(false); } // Always retry on client exceptions caused by WebException which has not been converted to // BceServiceException. if (exception.InnerException is WebException) { log.Debug("Retry for WebException."); return(true); } // Always retry on client exceptions caused by IOException if (exception.InnerException is IOException) { log.Debug("Retry for IOException."); return(true); } // Only retry on a subset of service exceptions if (exception is BceServiceException) { BceServiceException bse = exception as BceServiceException; /* * For 500 internal server errors and 503 service unavailable errors, we want to retry, but we need to use * an exponential back-off strategy so that we don't overload a server with a flood of retries. */ if (bse.StatusCode == BceConstants.HttpStatusCode.InternalServerError) { log.Debug("Retry for internal server error."); return(true); } if (bse.StatusCode == BceConstants.HttpStatusCode.ServiceUnavailable) { log.Debug("Retry for service unavailable."); return(true); } string errorCode = bse.ErrorCode; if (errorCode == BceConstants.BceErrorCode.RequestExpired) { log.Debug("Retry for request expired."); return(true); } } return(false); }
/// <summary> /// convert HttpWebResponse to BceServiceException /// </summary> /// <param name="response">the input HttpWebResponse</param> /// <returns></returns> public static BceServiceException CreateFromHttpWebResponse(HttpWebResponse response) { BceServiceException bse = null; var content = response.GetResponseStream(); if (content != null) { var errorResponse = JsonUtils.ToObject <BceErrorResponse>(new StreamReader(content)); if (errorResponse != null && errorResponse.Message != null) { bse = new BceServiceException(errorResponse.Message); bse.ErrorCode = errorResponse.Code; bse.RequestId = errorResponse.RequestId; } } if (bse == null) { bse = new BceServiceException(response.StatusDescription); bse.RequestId = response.Headers[BceConstants.HttpHeaders.BceRequestId]; } bse.StatusCode = (int)response.StatusCode; return(bse); }