46

Suppose that I have some global Ajax event handlers defined (ajaxStart, ajaxStop, and ajaxError). Usually I am fine with that, but for one request, I want to disable the ajaxError handler but still run the ajaxStart and ajaxStop handlers as usual. The jQuery ajax function documentation mentions the "global" parameter that can be set to false and passed to the $.ajax function to disable all global Ajax event handlers, but they don't mention any way to only disable some global handlers.

I can prevent the ajaxError handler by doing a test on the "url" property of the ajaxSettings object that is passed to the ajaxError function, but that seems somewhat clumsy. Does anyone here know of a way to disable the ajaxError function from running that would be clear to someone looking at the place where the $.ajax function is being called?

I can provide a simple example if anyone wants to see it.

Elias Zamaria
  • 96,623
  • 33
  • 114
  • 148
  • Have you tried (and I'm guessing on this one) adding your own `.error` handler into the `$.ajax()` call and then putting `return false` at the end of the function to stop processing? – Dan Short Sep 15 '11 at 19:16
  • Yes, I tried that. It didn't fix the problem. The global handler still ran. – Elias Zamaria Sep 15 '11 at 19:21
  • The global handler (success,error,complete) runs before the success/error/complete handler if I remember correctly. – Vlad Nicula Sep 22 '11 at 12:27

4 Answers4

97

It's possible and not difficult to do.

You just need to setup your global error handler (.ajaxError) to receive a few of the parameters that jQuery can provide to it:

$("div.log").ajaxError(function(evt, xhr, settings) {
    if(settings.suppressErrors) {
        return;
    }

    // Normal processing
});

After this, you can add suppressErrors: true to the settings of any AJAX request you make, and if it fails the error handler will return without doing what it normally does.

See it in action.

Jon
  • 428,835
  • 81
  • 738
  • 806
  • This looks like the best answer so far. I like your example. – Elias Zamaria Sep 19 '11 at 17:51
  • I tried your idea and it worked. I will probably award the bounty to you, unless someone else can come up with a more elegant solution. – Elias Zamaria Sep 19 '11 at 18:50
  • This answer is completely adequate for my needs so I decided to award the bounty to you. – Elias Zamaria Sep 22 '11 at 23:30
  • Other option: `if(settings.error !== undefined) { return; };` Then on normal ajax query, just set error: to something – Karman De Lange Feb 10 '14 at 14:33
  • 2
    Adding fields to an object we don't actually own seems... icky. – Jimmy Breck-McKye Jul 15 '15 at 12:37
  • 1
    @JimmyBreck-McKye: I totally understand your unease, but the options object is intended to be used exactly like that -- see e.g. examples at http://api.jquery.com/jquery.ajaxprefilter/ – Jon Jul 15 '15 at 13:59
  • 1
    @Jon - fair enough - if the docs give an example of us using the object in that way, it seems we should be able to rely on it. I might still be tempted to prefix my field name to avoid the slight chance of a naming collision someday, though. – Jimmy Breck-McKye Jul 16 '15 at 11:46
  • Is the object that suppressErrors is on accessible from the local ajax error handler? I.e. `$.ajax({ error: function(...) { if(...) xhr.suppressErrors = true` – AaronLS Oct 22 '19 at 19:57
15

When you look at this if statement from the jquery/ajax source https://github.com/jquery/jquery/blob/master/src/ajax.js#L579-582 , which is one of many of the same kind, it is clear that your problem can not be solved by a jquery parameter alone.

My suggestion would be to:

  • set global to false, like Vaibhav Gupta said

  • map your global handlers to local in the specific ajax call and trigger the global event through the $.event.trigger method

Sample:

$.ajax({
    url: "test.html",
    global: false,
    beforeSend: function(){$.event.trigger('ajaxStart');},
    complete: function(){$.event.trigger('ajaxStop');},
    error: your_error_handler
});
topek
  • 18,609
  • 3
  • 35
  • 43
  • This looks like it may prevent the error handler, but it may cause other subtle problems. The beforeSend handler is only supposed to run when the first Ajax request begins. It is not supposed to run if there is already another Ajax request going on. The ajaxStop function runs when all Ajax requests stop. It should not run if there are other Ajax requests. I still may try your answer anyway if I don't see anything better. – Elias Zamaria Sep 19 '11 at 17:56
  • According to jQuery's source (https://github.com/jquery/jquery/blob/master/src/ajax.js#L659-661) jQuery is using a public available counter jQuery.active. I confirmed that you can use this to fire the global event. Example: beforeSend: function(){if(jQuery.active === 0) {$.event.trigger('ajaxStart')}} – topek Sep 19 '11 at 18:56
9

try to use global: false in your ajax request like:

 $.ajax({
   url: "test.html",
   global: false,
   // ...
 });

source:: http://docs.jquery.com/Ajax_Events

Look for Global Events.

Vaibhav Gupta
  • 1,592
  • 1
  • 13
  • 23
9

You can set $.event.global.ajaxError to false to disable invoking the global error callback temporarily. Use the error and complete callbacks of your special request to set the flags:

$.ajax({
    url: 'some.domain.com/',
}).error(function(jXHR){
    // Disable global error logging
    $.event.global.ajaxError = false;
}).complete(function(){
    // Enable global error logging
    $.event.global.ajaxError = true;
});

An example is available on jsFiddle.

That being presented, I want to add that I would still prefer Jon's proposal. This technique requires to set the flag at 2 places of which you could forget one and and up to have the global handlers disabled accidentally. The other reason is that Jon's technique should be guaranteed to work across jQuery releases where setting some internal flags is not reliable.

Augustus Kling
  • 3,303
  • 1
  • 22
  • 25