/// <summary> /// Translates the data service client exception. /// </summary> /// <param name="e">The exception.</param> /// <returns>The translated exception.</returns> internal static Exception TranslateDataServiceClientException(InvalidOperationException e) { var dsce = CommonUtils.FindInnerDataServiceClientException(e); if (dsce == null) { return(e); } return(TranslateFromHttpStatus( (HttpStatusCode)dsce.StatusCode, null, GetExtendedErrorFromXmlMessage(dsce.Message), e)); }
/// <summary> /// Executes the segmented impl. /// </summary> /// <param name="continuationToken">The continuation token.</param> /// <param name="setResult">The set result.</param> /// <returns>A <see cref="TaskSequence"/> that executes the query and returns the first segment of results.</returns> internal TaskSequence ExecuteSegmentedImpl(ResultContinuation continuationToken, Action <ResultSegment <TElement> > setResult) { var localQuery = this.query; localQuery = RewriteQueryForTakeCount(localQuery, this.pagination); localQuery = ApplyContinuationToQuery(continuationToken, localQuery); var requestTask = localQuery.ExecuteAsync(); yield return(requestTask); try { var responseResult = requestTask.Result; var response = responseResult as QueryOperationResponse; ResultContinuation newContinuationToken = this.GetTableContinuationFromResponse(response); List <TElement> listResult = new List <TElement>(responseResult.ToList()); ResultSegment.CreateResultSegment <TElement>( setResult, listResult, newContinuationToken, this.pagination, this.RetryPolicy, (scratch, continuationArg, setResultInnerArg) => this.ExecuteSegmentedImpl(continuationArg, setResultInnerArg)); } catch (InvalidOperationException ex) { var dsce = CommonUtils.FindInnerDataServiceClientException(ex); if (dsce == null) { throw; } if ((HttpStatusCode)dsce.StatusCode == HttpStatusCode.NotFound) { setResult(new ResultSegment <TElement>(new List <TElement>(), false, null, null)); } throw; } }
/// <summary> /// Gets the result or default. /// </summary> /// <typeparam name="T">The type of the result.</typeparam> /// <param name="task">The task to retrieve the result from.</param> /// <param name="result">Receives result of the task.</param> /// <returns><c>true</c> if the result was returned; otherwise, <c>false</c>.</returns> private static bool GetResultOrDefault <T>(Task <T> task, out T result) { try { result = task.Result; return(true); } catch (DataServiceQueryException ex) { if ((HttpStatusCode)ex.Response.StatusCode == HttpStatusCode.NotFound) { result = default(T); return(false); } throw Utilities.TranslateDataServiceClientException(ex); } catch (InvalidOperationException ex) { DataServiceClientException dsce = CommonUtils.FindInnerDataServiceClientException(ex); if (dsce != null) { if ((HttpStatusCode)dsce.StatusCode == HttpStatusCode.NotFound) { result = default(T); return(false); } } throw Utilities.TranslateDataServiceClientException(ex); } }
/// <summary> /// Implementation of the *RequestWithRetry methods. /// </summary> /// <typeparam name="T">The result type of the task.</typeparam> /// <param name="retryOracle">The retry oracle.</param> /// <param name="impl">The task implementation.</param> /// <param name="setResult">The result report delegate.</param> /// <returns>A <see cref="TaskSequence"/> that performs the request with retries.</returns> internal static TaskSequence RequestWithRetryImpl <T>(ShouldRetry retryOracle, Func <Action <T>, TaskSequence> impl, Action <T> setResult) { int retryCount = 0; bool succeeded = false; bool shouldRetry = false; do { var task = new InvokeTaskSequenceTask <T>(impl); yield return(task); TimeSpan delay = TimeSpan.FromMilliseconds(-1); try { var result = task.Result; succeeded = true; setResult(result); } catch (TimeoutException e) { shouldRetry = retryOracle != null?retryOracle(retryCount ++, e, out delay) : false; // We should just throw out the exception if we are not retrying if (!shouldRetry) { throw; } } catch (StorageServerException e) { if (e.StatusCode == HttpStatusCode.NotImplemented || e.StatusCode == HttpStatusCode.HttpVersionNotSupported) { throw; } shouldRetry = retryOracle != null?retryOracle(retryCount ++, e, out delay) : false; // We should just throw out the exception if we are not retrying if (!shouldRetry) { throw; } } catch (InvalidOperationException e) { DataServiceClientException dsce = CommonUtils.FindInnerDataServiceClientException(e); // rethrow 400 class errors immediately as they can't be retried // 501 (Not Implemented) and 505 (HTTP Version Not Supported) shouldn't be retried either. if (dsce != null && ((dsce.StatusCode >= 400 && dsce.StatusCode < 500) || dsce.StatusCode == (int)HttpStatusCode.NotImplemented || dsce.StatusCode == (int)HttpStatusCode.HttpVersionNotSupported)) { throw; } // If it is BlobTypeMismatchExceptionMessage, we should throw without retry if (e.Message == SR.BlobTypeMismatchExceptionMessage) { throw; } shouldRetry = retryOracle != null?retryOracle(retryCount ++, e, out delay) : false; // We should just throw out the exception if we are not retrying if (!shouldRetry) { throw; } } if (!succeeded && shouldRetry && delay > TimeSpan.Zero) { using (DelayTask delayTask = new DelayTask(delay)) { yield return(delayTask); // Materialize exceptions var scratch = delayTask.Result; } } }while (!succeeded && shouldRetry); }
/// <summary> /// Implementation of the *RequestWithRetry methods. /// </summary> /// <typeparam name="TResult">The result type of the task.</typeparam> /// <param name="retryOracle">The retry oracle.</param> /// <param name="syncTask">The task implementation.</param> /// <returns>A <see cref="TaskSequence"/> that performs the request with retries.</returns> internal static TResult RequestWithRetrySyncImpl <TResult>(ShouldRetry retryOracle, SynchronousTask <TResult> syncTask) { int retryCount = 0; bool shouldRetry = false; do { TimeSpan delay = TimeSpan.FromMilliseconds(-1); try { return(syncTask.Execute()); } catch (TimeoutException e) { shouldRetry = retryOracle != null?retryOracle(retryCount ++, e, out delay) : false; // We should just throw out the exception if we are not retrying if (!shouldRetry) { throw; } } catch (StorageServerException e) { if (e.StatusCode == HttpStatusCode.NotImplemented || e.StatusCode == HttpStatusCode.HttpVersionNotSupported) { throw; } shouldRetry = retryOracle != null?retryOracle(retryCount ++, e, out delay) : false; // We should just throw out the exception if we are not retrying if (!shouldRetry) { throw; } } catch (InvalidOperationException e) { DataServiceClientException dsce = CommonUtils.FindInnerDataServiceClientException(e); // rethrow 400 class errors immediately as they can't be retried // 501 (Not Implemented) and 505 (HTTP Version Not Supported) shouldn't be retried either. if (dsce != null && ((dsce.StatusCode >= 400 && dsce.StatusCode < 500) || dsce.StatusCode == (int)HttpStatusCode.NotImplemented || dsce.StatusCode == (int)HttpStatusCode.HttpVersionNotSupported)) { throw; } // If it is BlobTypeMismatchExceptionMessage, we should throw without retry if (e.Message == SR.BlobTypeMismatchExceptionMessage) { throw; } shouldRetry = retryOracle != null?retryOracle(retryCount ++, e, out delay) : false; // We should just throw out the exception if we are not retrying if (!shouldRetry) { throw; } } if (shouldRetry && delay > TimeSpan.Zero) { Thread.Sleep(delay); } }while (shouldRetry); throw new StorageClientException( StorageErrorCode.None, "Unexpected internal storage client error.", System.Net.HttpStatusCode.Unused, null, null) { HelpLink = "http://go.microsoft.com/fwlink/?LinkID=182765" }; }