I am using a Windows Forms Application to create a massive amount of items in various lists inside a SharePoint Online site based on information that the application gets from a JSON file. The application gets its permissions by executing as a SharePoint user. It uses CSOM.
Sometimes when I use that application with exactly the same input that I used before (same site, same unchanged JSON file, etc.) I get following error:
Microsoft.SharePoint.Client.ServerException: Ending value cannot be less than starting value. Parameter name: endingValue at Microsoft.SharePoint.Client.ClientRequest.ProcessResponseStream(Stream responseStream) at Microsoft.SharePoint.Client.ClientRequest.ProcessResponse() at Microsoft.SharePoint.Client.ClientRequest.ExecuteQueryToServer(ChunkStringBuilder sb) at Microsoft.SharePoint.Client.ClientRequest.ExecuteQuery() at Microsoft.SharePoint.Client.ClientRuntimeContext.ExecuteQuery() at Microsoft.SharePoint.Client.ClientContext.ExecuteQuery()**
The function in which I call "ExecuteQuery" is always the following:
public static void ExecuteQueryWithIncrementalRetry(this ClientContext context, int retryCount, int delay)
{
int retryAttempts = 0;
int backoffInterval = delay;
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
{
context.ExecuteQuery();
return;
}
catch (System.Net.WebException wex)
{
var response = wex.Response as System.Net.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 == (System.Net.HttpStatusCode)429 || response.StatusCode == (System.Net.HttpStatusCode)503))
{
//Add delay for retry
System.Threading.Thread.Sleep(backoffInterval);
//Add to retry count and increase delay.
retryAttempts++;
// if backoffInterval == 30000, then it will be 60000 (1 Minute) (doubled)
// next raise it to five minutes
if (backoffInterval == 60000) { backoffInterval = 300000; }
else
{
// next raise it to 15 minutes
if (backoffInterval == 300000) { backoffInterval = 900000; }
else
{
// next raise it to 30 minutes
if (backoffInterval == 900000) { backoffInterval = 18000000; }
else
{
backoffInterval = backoffInterval * 2;
}
}
}
}
else
{
throw;
}
}
}
throw new MaximumRetryAttemptedException(string.Format("Maximum retry attempts {0}, has be attempted.", retryCount));
}
This function worked several times when I tested it and should deal with SharePoint throttling the application when it uses ExecuteQuery() many times in a row (sadly there seems to be no way to avoid that in my application; I did not create this function myself, it's a slightly changed function that I found and usually works).
I feel like the exception has something to do with the throttling by SharePoint Online because of the huge amount of requests that are being made when I run the app. The error definitely is not the usual error that I see when I get throttled, but I can't find any other explanation.
My first thought was that this error could have occured because of invalid data in the list item's Datetime-Fields ( when the value in the field "Modified" is smaller than the one I in the field "Created"). But that's apparently not the case, especially since this error does not always occur, when I run the tool using exactly the same data.
I always get the error at different spots in my code at different times with the same input, but always when I execute the query.
Do you have any ideas what could cause this exception or how I could avoid/ work around it?