Global AJAX error handling with jQuery
Error handling and feedback for AJAX requests can be a tedious undertaking for JavaScript heavy web applications. Often the AJAX functions are spread out in your code and, if you're like me, you may put off error handling until late in the game.
In a significant web project we're wrapping up, we were struggling to effectively handle session expiration issues when making AJAX calls. A major portion of this application uses AJAX and jQuery to perform the primary tasks in the software but the authentication is handled by .NET forms authentication on the server side. The sliding expiration is only 20 minutes, so when you walk away for a bit and return, you could easily create a new AJAX action which would fail silently due to an unauthorized error.
Our options as we saw them were:
- Ping the server periodically to check for authorization, then redirect if unauthorized
- Add an error handling function to each AJAX function to deal with problems
- Add global error handling if possible
It turns out that, with JQuery, option 3 is trivial and exactly what we needed.
AJAX Setup
jQuery has a handy method called $.ajaxSetup() which allows you to set options that apply to all jQuery based AJAX requests that come after it. By placing this method in your main document ready function, all of the settings will be applied to the rest of your functions automatically and in one location.
$(function () { //setup ajax error handling $.ajaxSetup({ error: function (x, status, error) { if (x.status == 403) { alert("Sorry, your session has expired. Please login again to continue"); window.location.href ="/Account/Login"; } else { alert("An error occurred: " + status + "nError: " + error); } } }); });
In this example, we're using the $.ajaxSetup method to define an on error handler. In this handler we check for a HTTP Response code 403 (Forbidden) and if found, redirect to the login screen. This solved our problem across the entire application in one shot. Additionally we add a very basic and generic error message if a request should fail for a different reason.
Additional Considerations
The $.ajaxSetup method accepts all of the parameters that a normal jQuery $.ajax method does and makes each of those settings the default action for future AJAX requests. Individual AJAX requests can easily override the defaults by specifying that option in the request.
You may be thinking, that's all well and good but does that mean I have to rewrite all of my shortcut calls to $.get, $.post, $.getJSON, $getScript, and $.load? The answer is No. Since the underlying call for each of these methods actually is the standard $.ajax call, they will all work with your new $.ajaxSetup defaults.
Now go forth and handle errors!
5 Comments
Leave a Reply
Meet the Author
Matthew Mombrea
Matt is our Chief Technology Officer and one of the founders of our agency. He started Cypress North in 2010 with Greg Finn, and now leads our Buffalo office. As the head of our development team, Matt oversees all of our technical strategy and software and systems design efforts.
With more than 19 years of software engineering experience, Matt has the knowledge and expertise to help our clients find solutions that will solve their problems and help them reach their goals. He is dedicated to doing things the right way and finding the right custom solution for each client, all while accounting for long-term maintainability and technical debt.
Matt is a Buffalo native and graduated from St. Bonaventure University, where he studied computer science.
When he’s not at work, Matt enjoys spending time with his kids and his dog. He also likes to golf, snowboard, and roast coffee.
Hey great post and great solution. One question: say one of your ajax calls has a different exception (say 402) you want to handle on top of the 403 error. Overriding the error handler and then handling them both doesn't seem ideal (duplicate code). Is there an elegant way that the 403 errors are handled by the error handler set in .ajaxsetup, and your 402 error is handled by the error handler you passed to the specific ajax call.
Haji,
That's a good question, I'm not sure I know the answer to that. If it's possible for other calls to get a 402 response, I might add it into the global error handler. As far as overriding for the one specific error then falling back to the global handler, I don't know of a way to do that (that doesn't mean there isn't one).
Thanks for the response! Might have to do more research on this 🙂
Note that this method of error handling is considered bad practice. The jQuery documentation strongly discourages the use of the $.ajaxSetup() api. This is noted in the documentation that you've linked in your post.
Best practice is to use global error handlers for the purpose you're describing in this post. See the documentation for implementation information http://api.jquery.com/category/ajax/global-ajax-event-handlers/
Thanks, I needed this!