18

I'm using jQuery.ajax() to connect to my back end service. I have configured an error() handler and a statusCode() handler. They both work fine, but when my statusCode handler gets fired the error handler also fires (the error handler is actually fired first). I would prefer this not to happen. I am assuming this is possible without having to hack the error handler code?

My code looks something like this:

$.ajax({
    ...
    error: function(...) { 
        // process a general type of error here
    },
    statusCode: {
        401: function() {
            // process a specific authentication failure
        }
    }                 
});

So how can I avoid the error() handler firing when the HTTP status code is 401?

Thanks for bothering to read!

1
  • 2
    I wonder if it would be worth requesting the jquery team, to make it so when you return false in 'statusCode' handlers it would prevent the ajax event propagating up to the 'error' handler. Surely this would not require much effort, while making it easier to write an application where unauthenticated requests all have the same global handler, ie: one function to return a user to the login screen. Commented Oct 31, 2012 at 21:06

5 Answers 5

12

You can easily check the status code inside the error callback. The first parameter should be XMLHttpRequest (or jqHXR depeding on your version of jQuery) object. Check the 'status' property for the status code of the error handle accordingly.

E.g.

error: function(a, b, c){
  if(a.status != 401){
    // handle other errors except authentication

  }
}
Sign up to request clarification or add additional context in comments.

5 Comments

Yes, but I was hoping to avoid having to hack the error handler as I mentioned in the original post. From what I understand this can't be done which strikes me as a little odd...
@LeeFrancis, oh I see what you mean. Couldn't you just write a wrapper that uses the $.ajax calls. You could then specify which status codes you want to suppress in the error handler? I writer wrappers for my all ajax calls so I can do any tweaking in one place. Just a thought...
Yes, that's more or less what I ended up doing in the end. However, I feel like I'm defeating the purpose of having the library pre-defined handlers available (success etc.) when you're checking the status codes manually anyway.
I tend to like jQuery. This problem hurts my brain because it should have been thought out up front during the design as this seems like a fairly common use case for those utilizing AJAX =\
@Lo-Tan True, but that's actually what I like about jQuery. In simple cases you can use it out of the box, but when you need more specific behaviour it's easy to write wrappers around the existing framework. In the case of Ajax I have written my own wrapper/plugin to encapsulate all my AJAX calls. That way I can get standardised behaviour across my apps and still use the jQuery methods at a lower level. Each to their own though. :]
7

Without hacking jQuery.ajax, you can't. To me, jQuery's ajax methods is one of the sore points of the library. For more sensible request handling, I recommend you look into superagent or some other stand-alone library.

1 Comment

Although not really what I wanted to hear, I guess this as close as I can get to an answer. Thanks.
6

Improving on the previous workarounds that require hard coding the status codes for which you do not want to fire the generic event handler.

In my opinion it is safer to edit your error handler since beforeSend might get overwritten for some other purpose and you can therefore inadvertently fire the generic error handler on those calls. (If someone overwrites the error callback they expect it to affect the error handling, if they modify the beforeSend callback they do not).

So you would get:

function ajaxError (jqXHR, textStatus, errorThrown)
{
    if (jqXHR.status in this.statusCode) return;
    // Handle generic events here.

}

1 Comment

This is pretty clever.
2

You can try using ajaxSetup and beforeSend to tweak the error handler of your ajax request automatically:

$.ajaxSetup({
  beforeSend: function(jqXHR, settings) {
    if (typeof settings.error === 'function') {
      var errorfunc = settings.error;
      settings.error = function(jqXHR2, textStatus, errorThrown) {
        if (jqXHR2.status !== 401) errorfunc(jqXHR2, textStatus, errorThrown);
      };
    }
  }
});

In my case this works.

2 Comments

Very nice. However, can it be made to work when error handler is set with fail() on the deferred returned by $.ajax?
I haven't tried, but according to the callback execution order of the jQuery jqXHR object (error before fail, see api.jquery.com/jQuery.ajax) you can probably modify the deferred's callbacks within the function replacing the original settings.error.
0

Check out the answer in this post about handling status codes with the error method: how to get jquery ajax status code

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.