Monday, May 15, 2023

Method for Managing Sharepoint online throttling for http status code 429 and 503, "Response status code does not indicate success: 429 ()."

 public static void ExecuteQueryWithIncrementalRetry(this ClientContext clientContext, int retryCount, int delay)

{ int retryAttempts = 0; int backoffInterval = delay; int retryAfterInterval = 0; bool retry = false; ClientRequestWrapper wrapper = null; if (retryCount <= 0) throw new ArgumentException("Provide a retry count greater than zero."); if (delay <= 0) throw new ArgumentException("Provide a delay greater than zero."); // Do while retry attempt is less than retry count while (retryAttempts < retryCount) { try { if (!retry) { clientContext.ExecuteQuery(); return; } else { //increment the retry count retryAttempts++; // retry the previous request using wrapper if (wrapper != null && wrapper.Value != null) { clientContext.RetryQuery(wrapper.Value); return; } // retry the previous request as normal else { clientContext.ExecuteQuery(); return; } } } catch (WebException ex) { var response = ex.Response as HttpWebResponse; // Check if request was throttled - http status code 429 // Check is request failed due to server unavailable - http status code 503 if (response != null && (response.StatusCode == (HttpStatusCode)429 || response.StatusCode == (HttpStatusCode)503)) { wrapper = (ClientRequestWrapper)ex.Data["ClientRequest"]; retry = true; // Determine the retry after value - use the `Retry-After` header when available string retryAfterHeader = response.GetResponseHeader("Retry-After"); if (!string.IsNullOrEmpty(retryAfterHeader)) { if (!Int32.TryParse(retryAfterHeader, out retryAfterInterval)) { retryAfterInterval = backoffInterval; } } else { retryAfterInterval = backoffInterval; } // Delay for the requested seconds Thread.Sleep(retryAfterInterval * 1000); // Increase counters backoffInterval = backoffInterval * 2; } else { throw; } } } throw new MaximumRetryAttemptedException($"Maximum retry attempts {retryCount}, has be attempted."); } [Serializable] public class MaximumRetryAttemptedException : Exception { public MaximumRetryAttemptedException(string message) : base(message) { } }