Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery $.ajax, error handler doesn't work

Hello I noticed that this simple code doesn't work the way it is supposed to work...

    function test() {
    $.ajax( {
        'url' : 'test/GameConfiguration.json',
        'dataType' : 'json',
        data : {
            a : 'aaa'
        },
        cache : false,
        method : 'get',
        timeout : 10000, //10 secs of timeout 
        success : function(data, textStatus, XMLHttpRequest) {
            console.log("success");
            if (data == null)
                console.log("it's not a real success");
        },
        error : function(XMLHttpRequest, textStatus, errorThrown) {
            console.log("error: " + textStatus);
        }
    });
}

The test has been run on localhost, I mean: I load the page, I shut down the local webserver, then I fire the request (via a simple button with onclick pointing to this function). Error doesn't ever get called, what I get is to have the success handler called and it has textStatus = "success" and data = null. I even notice that the request times out long before 10 seconds. This happens on Firefox (last version), Chrome (last version) and Safari 5. Why this? Is it due to the fact I'm working on localhost?


I forgot to tell: THE Request isn't cached. In fact both firebug and Chrome dev tools show the request to fail.


Big update

This behaviour is related to the use of localhost. In fact if I load this page from another collegue PC and before triggering the request I disconnect my PC from the network, I correctly get the error handler fired with timeout as status. I think this is a bug of jQuery. It will make me hard to test the timeout errors :(


Guys from jQuery forums say this is due to the way the network stack aborts the connection, given that the host is localhost. I tested this on Windows 7 only. If you feel like testing this on other systems and you can work out some jQuery internals, report to this post at the jQuery forums:

http://forum.jquery.com/topic/strange-and-unexpected-behaviour-of-ajax-error-and-localhost#14737000001331961

like image 378
gotch4 Avatar asked Sep 01 '10 09:09

gotch4


2 Answers

UPDATED: Try to replace the test (data == null) to the (XMLHttpRequest.readyState === 4 && XMLHttpRequest.status === 0).

In W3C Candidate Recommendation about XMLHttpRequest standard is described that it must exist so named "error flag" which should be used to indicates some type of network error or abortion. In case of such kind of errors the status in the XMLHttpRequest will be 0 instead of 200 ("OK"), 201 ("Created"), 304 ("Not Modified") and so on. To be exactly corresponds to http://www.w3.org/TR/XMLHttpRequest/#the-status-attribute the XMLHttpRequest.status can be 0 in case of XMLHttpRequest.readyState equal to 0 or 1 ("UNSENT" or "OPENED"). Another case is XMLHttpRequest.readyState equal to 4 ("DONE") and "error flag" is true. If we have no from these two cases the XMLHttpRequest.status must be a HTTP status code. Under http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html or http://www.w3.org/Protocols/HTTP/1.0/spec.html#Status-Codes there are no HTTP status code equal to 0. So it seems to my that you can do following

jQuery(document).ready(function () {
    $.ajax({
        type: 'GET',
        url:  'test/GameConfiguration.json',
        dataType: 'json',
        cache : false,
        success: function(data, textStatus, xhr){
            if (xhr.readyState === 4 && xhr.status === 0) {
                // if readyState is DONE (numeric value 4) then corresponds to
                // http://www.w3.org/TR/XMLHttpRequest/#dom-xmlhttprequest-done
                // "The DONE state has an associated error flag that indicates
                // some type of network error or abortion."
                // Corresponds to http://www.w3.org/TR/XMLHttpRequest/#the-status-attribute
                // If error flag it true, xhr.status is 0.
                alert('"error flag\" is true. It means that we have a network error"+
                      " or abortion (for example because of Same Origin Policy restrictions)');
            }
            else {
                alert(textStatus);
                alert(data);
            }
        },
        error: function(xhr, textStatus, errorThrown) {
            if (textStatus !== null) {
                alert("error: " + textStatus);
            } else if (errorThrown !== null) {
                alert("exception: " + errorThrown.message);
            }
            else {
                alert ("error");
            }
        }
    });
});
like image 142
Oleg Avatar answered Oct 25 '22 00:10

Oleg


If there's a network error the success callback will be called and not the error even if it doesn't make much sense. Checkout this blog post for details. So basically what you've done by checking data == null is correct.

like image 20
Darin Dimitrov Avatar answered Oct 25 '22 00:10

Darin Dimitrov