Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Catching 302 error and then redirecting in backbone.js sync method override

What I want to do is catch a 302 error which means a user is not logged in, and then redirecting that user to the login page of the website. Here's my backbone.js sync override right now:

parentSynchMethod = Backbone.sync
Backbone.sync = (method, model, success, error) -> 
  try
    parentSynchMethod.apply(Backbone, arguments)
  catch error
    window.location.replace("http://localhost:8080/login")

The 302 error is definitely happening, I can see it in the network view when I inspect the page using google chrome. However, when I set a breakpoint, it never goes inside the catch, and the error argument is undefined. Is this because 302 is not a real error(it's yellow when I view the status of the response, instead of a usual red for errors, or am I messing up the code somewhere.

like image 775
prashn64 Avatar asked Apr 19 '12 21:04

prashn64


1 Answers

The default Backbone.sync doesn't raise an exception when the AJAX request returns an error condition (and yes, 302 is an error), it leaves the error handling to $.ajax. The default sync looks like this:

Backbone.sync = function(method, model, options) {
  // A bunch of bureaucratic setup and what not...

  // Make the request, allowing the user to override any Ajax options.
  return Backbone.ajax(_.extend(params, options));
};

and Backbone.ajax is just $.ajax; note that the above is the current master branch of Backbone, the currently released version uses $.ajax directly.

What you want to do is replace Backbone.sync with something that always forces an error handler like this:

error: (xhr, text_status, error_thrown) ->
    if(xhr.status == 302)
        window.location.replace('http://localhost:8080/login')
    else
        # call the supplied error handler if any

Something like this should do the trick:

parentSynchMethod = Backbone.sync
Backbone.sync = (method, model, options) ->
    old_error = options.error
    options.error = (xhr, text_status, error_thrown) ->
        if(xhr.status == 302)
            window.location.replace('http://localhost:8080/login')
        else
            old_error?(xhr, text_status, error_thrown)
    parentSyncMethod(method, model, options)

If you're using the master branch of Backbone (or reading this after Backbone.ajax is in the released version), then you could replace Backbone.ajax with something that forces an error handler as above and leave Backbone.sync alone.

like image 188
mu is too short Avatar answered Nov 08 '22 18:11

mu is too short