Second Life of a Hungarian SharePoint Geek

February 19, 2014

Fault-tolerant REST Queries

Filed under: jQuery, REST, SP 2010, SP 2013 — Tags: , , , — Peter Holpar @ 22:15

Recently I faced again with the problem, that as the scripts on my web pages submit REST queries after a longer pause or an IISRESET (that is, when the IIS application pools must be started), I receive on of the following errors on the first try:

‘Microsoft.SharePoint.DataService.ListNameItem’ does not have a property named ‘FieldName’. (SharePoint 2010, HTTP 400 – Bad Request in the browser)
An error occurred while processing this request.  (SharePoint 2010, HTTP 500 – Internal Server Error in the browser)
No property ‘FieldName’ exists in type ‘Microsoft.SharePoint.Linq.DataServiceEntity’ at position 0. (SharePoint 2013, HTTP 400 – Bad Request in the browser)

When one submits the query via the browser, only the HTTP 400 / HTTP 500 error codes are displayed. You can see the detailed error message only via a network traffic analyzer tool, like Fiddler.

The subsequent queries (even using the same expression as originally) usually succeed. If we submits multiple queries at the same time (for example via a script on a page), it might happen that several of these queries fail with the same error.

How to avoid this kind of failures in a web application, when it is especially important to prevent the erratic behavior?

Using jQuery we can create a function like the one below to re-submit the query automatically and silently in case of errors. I applied a time-gap of 1 second in the sample to give the system time to wake up and a maximum number of 3 retries. If even after the 3rd retry we encounter an error, we simply display it to the user.

// alter the value to match your site
var baseUrl = ‘http://yoursharepoint/yoursite/_vti_bin/listdata.svc/’;

function sendRESTQuery(queryUrl, onSuccess, retryCount) {
    var retryInterval = 1000; // 1 sec.
    var retryCountMax = 3;
    // use a default value of 0 if no value for retryCount passed
    var retryCount = (retryCount != undefined) ? retryCount : 0;

    $.ajax({
        type: ‘GET’,
        contentType: ‘application/json;odata=verbose’,
        url: baseUrl + queryUrl,
        headers: {
            ‘X-RequestDigest’: $(‘#__REQUESTDIGEST’).val(),
            "Accept": "application/json; odata=verbose"
        },
        dataType: "json",
        complete: function (result) {               
            var response = JSON.parse(result.responseText);
            if (response.error) {
                // here you can include your custom logic to differentiate for example based on the error types
                if (retryCount <= retryCountMax) {
                    window.setTimeout(function () { sendRESTQuery(queryUrl, onSuccess, retryCount++) }, retryInterval);
                }
                else {
                    alert("Error: " + response.error.code + "\n" + response.error.message.value);
                }
            }
            else {
                bgDetails = response.d;
                onSuccess(bgDetails);
            }
        }
    });      
}

Assuming we have a HTML page with a SELECT element having id = “dropItemList”, and a SharePoint list called YourList, the following code snippet demonstrates, how to fill up the options of the SELECT with the list items:

var dropItemListSelector = "#dropItemList";

function initDropItemList() {
    $(dropItemListSelector).hide();
    var queryUrl = "YourList()?$select=Id,Title";
    sendRESTQuery(queryUrl, function (responseData) {
        var items = responseData.results;
        $(dropItemListSelector).find(‘option’).remove().end().append(‘<option value="0">Please choose an item!</option>’);
        Enumerable.from(items).orderBy("$.Title").forEach(function (x) {
            $(‘<option>’).val(x.Id).text(x.Title).appendTo(dropItemListSelector);
        });
        $(dropItemListSelector).show();
    });       
}

In the previous example I used the linq.js ver.3.0.4-Beta5 to assemble my LINQ query. Version of the library is important!

1 Comment »

  1. Hey, there’s a jquery plugin that does this automagically for you. I did a post on it at http://yetanothersharepointblog.wordpress.com/2013/09/05/automatically-retry-jquery-ajax-calls-to-listdata-svc-after-500-errors/

    Keep up the great posts!
    Russell

    Comment by russgove — February 21, 2014 @ 22:18


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: