How do I catch jQuery $.getJSON (or $.ajax with datatype set to 'jsonp') error when using JSONP?

Is it possible to catch an error when using JSONP with jQuery? I've tried both the $.getJSON and $.ajax methods but neither will catch the 404 error I'm testing. Here is what I've tried (keep in mind that these all work successfully, but I want to handle the case when it fails):

jQuery.ajax({
    type: "GET",
    url: handlerURL,
    dataType: "jsonp",
    success: function(results){
        alert("Success!");
    },
    error: function(XMLHttpRequest, textStatus, errorThrown){
        alert("Error");
    }
});

And also:

jQuery.getJSON(handlerURL + "&callback=?", 
    function(jsonResult){
        alert("Success!");
    });

I've also tried adding the $.ajaxError but that didn't work either:

jQuery(document).ajaxError(function(event, request, settings){
   alert("Error");
});

Thanks in advance for any replies!

Answers:

Answer

It seems that JSONP requests that don't return a successful result never trigger any event, success or failure, and for better or worse that's apparently by design.

After searching their bug tracker, there's a patch which may be a possible solution using a timeout callback. See bug report #3442. If you can't capture the error, you can at least timeout after waiting a reasonable amount of time for success.

Answer

Detecting JSONP problems

If you don't want to download a dependency, you can detect the error state yourself. It's easy.

You will only be able to detect JSONP errors by using some sort of timeout. If there's no valid response in a certain time, then assume an error. The error could be basically anything, though.

Here's a simple way to go about checking for errors. Just use a success flag:

var success = false;

$.getJSON(url, function(json) {
    success = true;
    // ... whatever else your callback needs to do ...
});

// Set a 5-second (or however long you want) timeout to check for errors
setTimeout(function() {
    if (!success)
    {
        // Handle error accordingly
        alert("Houston, we have a problem.");
    }
}, 5000);

As thedawnrider mentioned in comments, you could also use clearTimeout instead:

var errorTimeout = setTimeout(function() {
    if (!success)
    {
        // Handle error accordingly
        alert("Houston, we have a problem.");
    }
}, 5000);

$.getJSON(url, function(json) {
    clearTimeout(errorTimeout);
    // ... whatever else your callback needs to do ...
});

Why? Read on...


Here's how JSONP works in a nutshell:

JSONP doesn't use XMLHttpRequest like regular AJAX requests. Instead, it injects a <script> tag into the page, where the "src" attribute is the URL of the request. The content of the response is wrapped in a Javascript function which is then executed when downloaded.

For example.

JSONP request: https://api.site.com/endpoint?this=that&callback=myFunc

Javascript will inject this script tag into the DOM:

<script src="https://api.site.com/endpoint?this=that&callback=myFunc"></script>

What happens when a <script> tag is added to the DOM? Obviously, it gets executed.

So suppose the response to this query yielded a JSON result like:

{"answer":42}

To the browser, that's the same thing as a script's source, so it gets executed. But what happens when you execute this:

<script>{"answer":42}</script>

Well, nothing. It's just an object. It doesn't get stored, saved, and nothing happens.

This is why JSONP requests wrap their results in a function. The server, which must support JSONP serialization, sees the callback parameter you specified, and returns this instead:

myFunc({"answer":42})

Then this gets executed instead:

<script>myFunc({"answer":42})</script>

... which is much more useful. Somewhere in your code is, in this case, a global function called myFunc:

myFunc(data)
{
    alert("The answer to life, the universe, and everything is: " + data.answer);
}

That's it. That's the "magic" of JSONP. Then to build in a timeout check is very simple, like shown above. Make the request and immediately after, start a timeout. After X seconds, if your flag still hasn't been set, then the request timed out.

Answer

If you collaborate with the provider, you could send another query string parameter being the function to callback when there's an error.

?callback=?&error=?

This is called JSONPE but it's not at all a defacto standard.

The provider then passes information to the error function to help you diagnose.

Doesn't help with comm errors though - jQuery would have to be updated to also callback the error function on timeout, as in Adam Bellaire's answer.

Answer

Seems like this is working now:

jQuery(document).ajaxError(function(event, request, settings){
   alert("Error");
});
Answer

I use this to catch an JSON error

try {
   $.getJSON(ajaxURL,callback).ajaxError();
} catch(err) {
   alert("wow");
   alert("Error : "+ err);
}

Edit: Alternatively you can get the error message also. This will let you know what the error is exactly. Try following syntax in catch block

alert("Error : " + err);
Answer

Mayby this works?

.complete(function(response, status) {
    if (response.status == "404")
        alert("404 Error");
    else{
        //Do something
    }   
    if(status == "error")
        alert("Error");
    else{
        //Do something
    }
});

I dont know whenever the status goes in "error" mode. But i tested it with 404 and it responded

Answer

you ca explicitly handle any error number by adding this attribute in the ajax request:

statusCode: {
        404: function() {
          alert("page not found");
        }
    }

so, your code should be like this:

jQuery.ajax({
type: "GET",
statusCode: {
        404: function() {
          alert("page not found");
        }
},
url: handlerURL,
dataType: "jsonp",
success: function(results){
    alert("Success!");
},
error: function(XMLHttpRequest, textStatus, errorThrown){
    alert("Error");
}
});

hope this helps you :)

Answer

I also posted this answer in stackoverflow - Error handling in getJSON calls

I know it's been a while since someone answerd here and the poster probably already got his answer either from here or from somewhere else. I do however think that this post will help anyone looking for a way to keep track of errors and timeouts while doing getJSON requests. Therefore below my answer to the question

The getJSON structure is as follows (found on http://api.jqueri.com):

$(selector).getJSON(url,data,success(data,status,xhr))

most people implement that using

$.getJSON(url, datatosend, function(data){
    //do something with the data
});

where they use the url var to provide a link to the JSON data, the datatosend as a place to add the "?callback=?" and other variables that have to be send to get the correct JSON data returned, and the success funcion as a function for processing the data.

You can however add the status and xhr variables in your success function. The status variable contains one of the following strings : "success", "notmodified", "error", "timeout", or "parsererror", and the xhr variable contains the returned XMLHttpRequest object (found on w3schools)

$.getJSON(url, datatosend, function(data, status, xhr){
    if (status == "success"){
        //do something with the data
    }else if (status == "timeout"){
        alert("Something is wrong with the connection");
    }else if (status == "error" || status == "parsererror" ){
        alert("An error occured");
    }else{
        alert("datatosend did not change");
    }         
});

This way it is easy to keep track of timeouts and errors without having to implement a custom timeout tracker that is started once a request is done.

Hope this helps someone still looking for an answer to this question.

Answer

Here's my extensive answer to a similar question.

Here's the code:

jQuery.getJSON(handlerURL + "&callback=?", 
    function(jsonResult){
        alert("Success!");
    })
.done(function() { alert('getJSON request succeeded!'); })
.fail(function(jqXHR, textStatus, errorThrown) { alert('getJSON request failed! ' + textStatus); })
.always(function() { alert('getJSON request ended!'); });
Answer

I know this question is a little old but I didn't see an answer that gives a simple solution to the problem so I figured I would share my 'simple' solution.

$.getJSON("example.json", function() {
      console.log( "success" );
}).fail(function() { 
      console.log( "error" ); 
}); 

We can simply use the .fail() callback to check to see if an error occurred.

Hope this helps :)

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.