JSONP request error handling

52,579

Solution 1

Two ways to handle error,

  1. There is no error handling for cross domain JSONP requests. Use jsonp plug-in available on Github https://github.com/jaubourg/jquery-jsonp that provides support for error handling.

  2. jQuery ajax Timeout - Timeout after a reasonable amount of time to fire the error callback because it might have failed silently. You may not know what the actual error (or error status) was but at least you get to handle the error

Solution 2

If you check jQuery.ajax() documentation, you can find:

error

A function to be called if the request fails (...) Note: This handler is not called for cross-domain script and cross-domain JSONP requests. This is an Ajax Event.

Because of that, you're forced to find workaround. You can specify timeout to trigger an error callback. It means that within specified time frame the request should be successfully completed. Otherwise, assume it has failed:

$.ajax({
    ...
    timeout: 5000, // a lot of time for the request to be successfully completed
    ...
    error: function(x, t, m) {
        if(t==="timeout") {
            // something went wrong (handle it)
        }
    }

});

Other issues in your code...

While JSONP (look here and here) can be used to overcome origin policy restriction, you can't POST using JSONP (see CORS instead) because it just doesn't work that way - it creates a element to fetch data, which has to be done via GET request. JSONP solution doesn't use XmlHttpRequest object, so it is not an AJAX request in the standard way of understanding, but the content is still accessed dynamically - no difference for the end user.

$.ajax({
    url: url,
    type: "GET"
    dataType: "jsonp",
    ...

Second, you provide data incorrectly. You're pushing javascript object (created using object literals) onto the wire instead of its serialized JSON representation. Create JSON string (not manually, use e.g. JSON.stringify converter):

$.ajax({
    ...
    data: JSON.stringify({u: userid, p: pass}),
    ...

Last issue, you've set async to false, while documentation says:

Cross-domain requests and dataType: "jsonp" requests do not support synchronous operation.

Solution 3

I've been struggling like you for a while trying to handle errors on ajax jsonp DataType requests, however I want to share you my code, hope it helps. A basic thing is to include a timeout on the ajax request, otherwise it'll never enter the error: function

$.ajax({
url: "google.com/api/doesnotexists",
dataType: "jsonp",
timeout: 5000,

success: function (parsed_json) {
console.log(parsed_json);
},

error: function (parsedjson, textStatus, errorThrown) {
console.log("parsedJson: " + JSON.stringify(parsedjson));

$('body').append(
    "parsedJson status: " + parsedjson.status + '</br>' + 
    "errorStatus: " + textStatus + '</br>' + 
    "errorThrown: " + errorThrown);        

 }
});

jsfiddle - Handle Errors with jquery ajax call and JSONP dataType - Error 404

Solution 4

I'm building a fragile JS project that uses jquery-jsonp, and came up with a dual-jsonp/ajax approach that handles errors no matter which method ends up being used.

function authenticate(user, pass) {
    var ajax = ($.jsonp || $.ajax)({
        'url': /* your auth url */,
        'data': { /* user, pass, ... */ },
        'contentType': "application/javascript",
        'dataType': 'jsonp',
        'callbackParameter': 'callback'  // $.jsonp only; $.ajax uses 'jsonpCallback'
    });
    ajax.done(function (data) {
        // your success events
    });
    ajax.fail(function (jqXHR, textStatus, errorThrown) {
        // $.jsonp calls this func as function (jqXHR, textStatus)
        // and $.ajax calls this func with the given signature
        console.error('AJAX / JSONP ' + textStatus + ': ' +
            (errorThrown || jqXHR.url));
    });
}

Since both jquery-jsonp and $.ajax support the jQuery Deferred specification, we can merge the two error handlers together, handling 400 and 500-series errors, as well as lookup timeouts.

Share:
52,579
Adrian Mojica
Author by

Adrian Mojica

Updated on December 06, 2020

Comments

  • Adrian Mojica
    Adrian Mojica over 3 years

    I'm making an ajax jsonp request, but the failure error handling wont work. If the request is 404 or 500 it won't handle the error.

    I've been looking around to find an answer to this, but can't find anything. There seems to be a solution with http://code.google.com/p/jquery-jsonp/, but I can't find any examples on how to use it.

    function authenticate(user, pass) {       
        $.ajax ({
            type: "POST",
            url: "url",
            dataType: 'jsonp',
            async: false,
            //json object to sent to the authentication url
            data: {"u": userid, "p": pass},
    
            success: function (data) {
                //successful authentication here
                console.log(data);
            },
            error: function(XHR, textStatus, errorThrown) {
                alert("error: " + textStatus);
                alert("error: " + errorThrown);
            }
        })
    }
    
  • claws
    claws about 10 years
    Method 2 is demostrated in the answer below: stackoverflow.com/a/19185826/193653
  • Hux
    Hux about 9 years
    Looking at this it initially appears to work, but unfortunately using "google.com/api/doesnotexists" will make jQuery request http://fiddle.jshell.net/_display/google.com, instead of google.com. If you prefix the url with http you will see the correct behaviour, where the timeout is observed and no status is returned.
  • Becca Dee
    Becca Dee almost 9 years
    Downvoted because I confirmed what @Mig reports; the URL requested is wrong in this example.
  • Tim McClure
    Tim McClure almost 9 years
    Just want to add that the AJAX documentation that is linked to in the answer above also states under the timeout parameter: In Firefox 3.0+ only, script and JSONP requests cannot be cancelled by a timeout; the script will run even if it arrives after the timeout period.
  • devwannabe
    devwannabe over 8 years
    Tim McClure. What Tim Mclure said is true and I've been searching the internet for 2+ days now trying to find a solution on how to handle the "Uncaught TypeError: jQuery110203912213369484832883_193467225 is not a function". Try-catch is not capturing it. I wrapped my $.ajax call with it but no luck.
  • Great Big Al
    Great Big Al about 8 years
    Good example, this worked for me, down-vote because of a pseudo URL? really!