Gaurav Dadhania
Gaurav Dadhania

Reputation: 5337

Invoke jQuery ajaxSuccess (or any global AJAX event) even if the local success (or any local AJAX event) throws an error

It is not mentioned in the docs, but apparently if the local AJAX success handler throws an error, even the global ajaxSuccess handler is not invoked. Is there a way around this mechanism cause if you want to distribute a JS library or util function that does something on ajaxSuccess, you can't necessarily have control over the success handler and make sure it does not raise an exception.

$(document).ajaxSuccess(function(ev, jqXHR, settings) {
  console.log('ajaxSuccess called!'); // does not get called
});

$.ajax({
  'url': '/',
  'type': 'GET',
  'success': function (response) {
    console.log('success called!');
    throw new Error();
  }
});

CodePen: http://codepen.io/anon/pen/Ldybr

Upvotes: 3

Views: 861

Answers (1)

Ilya Luzyanin
Ilya Luzyanin

Reputation: 8110

Here is the documentation that partially explains the issue you're facing:

Events
...
success (Local Event)
This event is only called if the request was successful (no errors from the server, no errors with the data).
ajaxSuccess (Global Event)
This event is also only called if the request was successful.
error (Local Event)
This event is only called if an error occurred with the request (you can never have both an error and a success callback with a request).
ajaxError (Global Event)
This global event behaves the same as the local error event.

This is the normal flow of events, i.e. any global event is called after local. But in case any callback throws exception, no other callback is called, because jQuery internally doesn't wrap the callback in try-catch (you may do this locally in your callback though).

Another solution, as I've mentioned in comments, is dataFilter property of ajax options, which allows you to perform needed actions before any local callback (success or error) is called. Here is demo from my comments to the question, just in case:

$.ajaxSetup({
  dataFilter: function(data, type) {
    console.log('dataFilter called!');
    return data;
  }
});

Upvotes: 3

Related Questions