239

I would like to catch the error and show the appropriate message if the Ajax request fails.

My code is like the following, but I could not manage to catch the failing Ajax request.

function getAjaxData(id)
{
     $.post("status.ajax.php", {deviceId : id}, function(data){

        var tab1;

        if (data.length>0) {
            tab1 = data;
        }
        else {
            tab1 = "Error in Ajax";
        }

        return tab1;
    });
}

I found out that, "Error in Ajax" is never executed when the Ajax request failed.

How do I handle the Ajax error and show the appropriate message if it fails?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
TTCG
  • 8,805
  • 31
  • 93
  • 141

8 Answers8

367

Since jQuery 1.5 you can use the deferred objects mechanism:

$.post('some.php', {name: 'John'})
    .done(function(msg){  })
    .fail(function(xhr, status, error) {
        // error handling
    });

Another way is using .ajax:

$.ajax({
  type: "POST",
  url: "some.php",
  data: "name=John&location=Boston",
  success: function(msg){
        alert( "Data Saved: " + msg );
  },
  error: function(XMLHttpRequest, textStatus, errorThrown) {
     alert("some error");
  }
});
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
choise
  • 24,636
  • 19
  • 75
  • 131
308

jQuery 1.5 added deferred objects that handle this nicely. Simply call $.post and attach any handlers you'd like after the call. Deferred objects even allow you to attach multiple success and error handlers.

Example:

$.post('status.ajax.php', {deviceId: id})
    .done( function(msg) { ... } )
    .fail( function(xhr, textStatus, errorThrown) {
        alert(xhr.responseText);
    });

Prior to jQuery 1.8, the function done was called success and fail was called error.

Michael Venable
  • 5,011
  • 3
  • 23
  • 20
  • 3
    +1 Very nice, but still not crazy about the syntax. Hopefully it gets unified in a future release. – Yuck Aug 24 '12 at 22:55
  • 31
    This should be the accepted answer. The current accepted answer is "use a different method"; this answer says "here's how to make your method work". The latter is usually preferred on SO. Actually, this should be included in the $.post documentation!!! – Mark E. Haase Dec 29 '13 at 18:53
  • 2
    http://api.jquery.com/deferred.fail , http://api.jquery.com/deferred.done for documentation – Deleplace Aug 22 '14 at 09:58
  • 2
    By the way there is also `responseJSON` property which is also very handy in case of ajax type is `json`. – ivkremer Apr 15 '15 at 16:06
  • 3
    `xhr.responseText` appears to be the needle in the fail-callback haystack. But I would suggest adding `dataType: 'text'` to the 2nd parameter to $.post. That [might](https://api.jquery.com/jQuery.Ajax/#data-types) help direct an error message of a different content-type to show up in responseText. But I haven't checked. – Bob Stein Dec 17 '21 at 14:48
99
$.ajax({
  type: 'POST',
  url: 'status.ajax.php',
  data: {
     deviceId: id
  },
  success: function(data){
     // your code from above
  },
  error: function(xhr, textStatus, error){
      console.log(xhr.statusText);
      console.log(textStatus);
      console.log(error);
  }
});
jAndy
  • 231,737
  • 57
  • 305
  • 359
18
$.post('someUri', { }, 
  function(data){ doSomeStuff })
 .fail(function(error) { alert(error.responseJSON) });
marknery
  • 1,533
  • 3
  • 19
  • 27
14

A simple way is to implement ajaxError:

Whenever an Ajax request completes with an error, jQuery triggers the ajaxError event. Any and all handlers that have been registered with the .ajaxError() method are executed at this time.

For example:

$('.log').ajaxError(function() {
  $(this).text('Triggered ajaxError handler.');
});

I would suggest reading the ajaxError documentation. It does more than the simple use-case demonstrated above - mainly its callback accepts a number of parameters:

$('.log').ajaxError(function(e, xhr, settings, exception) {
  if (settings.url == 'ajax/missing.html') {
    $(this).text('Triggered ajaxError handler.');
  }
});
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
karim79
  • 339,989
  • 67
  • 413
  • 406
  • 1
    +1 - I would add that this handler gets several arguments, so you can display the actual error, response code, url, etc. – Nick Craver May 14 '10 at 12:14
  • Note that as of jQuery 1.8, the .ajaxError() method should only be attached to document. – Nanki Apr 30 '15 at 11:00
3

You have to log the responseText:

$.ajax({
    type: 'POST',
    url: 'status.ajax.php',
    data: {
    deviceId: id
  }
})
.done(
 function (data) {
  //your code
 }
)
.fail(function (data) {
      console.log( "Ajax failed: " + data['responseText'] );
})
manolo
  • 31
  • 5
1

In case you want to utilize .then() which has a subtle difference in comparison with .done() :

return $.post(url, payload)
.then(
    function (result, textStatus, jqXHR) {
        return result;
    },
    function (jqXHR, textStatus, errorThrown) {
        return console.error(errorThrown);
    });
panagiotis
  • 1,521
  • 1
  • 9
  • 8
0

you attach the .onerror handler to the ajax object, why people insist on posting JQuery for responses when vanila works cross platform...

quickie example:

ajax = new XMLHttpRequest();
ajax.open( "POST", "/url/to/handler.php", true );
ajax.onerror = function(){
    alert("Oops! Something went wrong...");
}
ajax.send(someWebFormToken );
Mark Giblin
  • 1,086
  • 2
  • 13
  • 20
  • can't resist to try and answer the why : easier to read and debug, faster to implement, especially if you have lots of parameters, there are plenty of tools to generate beatiful $.ajax statement with their parameters – Tamtomo Abdi Negoro Jul 10 '23 at 10:42
  • Using a library all the time exposes you to any underlying bugs, exploits and you are reliant on the library and not raw code which IMHO is always a better option. Learn to code not to use a library, there is no rapid development with a library, that is a popular myth. – Mark Giblin Jul 11 '23 at 13:58