Catching Backbone sync errors

d4kris picture d4kris · May 10, 2013 · Viewed 9.5k times · Source

I needed to catch a possible login page in all responses from the server, so I have overridden Backbone.sync globally so I can check all errors before passing them on.

Backbone.originalSync = Backbone.sync;

Backbone.sync = function (method, model, options) {
    var originalSuccess, originalError;
    console.log("sync override...");
    // remember original success so we can call it if user logs in successfully
    originalSuccess = options.success;
    // proxy the error callback to first check if we get a login page back
    originalError = options.error;
    options.error = function (model, xhr, options) {
        if (xhr.status === 200 && xhr.responseText === "") {
            // parse error from empty response (jq1.9 invalid json, ok)
            originalSuccess(model, xhr, options);
        } else {
            console.log("Sync error " + statusTxt + ", " + thrown.message);
            if (xhr.status === 200 || xhr.status === 302 || xhr.status === 0) {
                // login page returned instead of json...
                // open a new window with relogon.html to trigger a new login
                window.showModalDialog("../relogon.html");
            } else {
                // normal error, pass along 
                if (originalError) {
                    originalError(model, xhr, options);
                }
            }
        }
    };

    // call the original sync
    Backbone.originalSync(method, model, options);
};

This broke miserably when going from 0.9.9 to 1.0. Looks like the original Backbone.sync wraps its error handlers differently, causing my error handler to be called first, with a jquery xhr signature. I had to change the signature of the error handler to this:

    options.error = function (xhr, statusTxt, thrown) {

Ok so now it works, but I get the feeling that I am doing something wrong.

Is there a better way to do this?

I tried with jquery promises but I need to be able to switch from error state to success (when calling originalSuccess), which did not seem to work with promises.

Answer

Andrey Kuzmin picture Andrey Kuzmin · May 10, 2013

All sync errors are passed to model's error event, so you may to listen to this event.

From http://backbonejs.org/#Events-catalog:

"error" (model, xhr, options) — when a model's save call fails on the server.

To capture error globally you may use http://api.jquery.com/ajaxError/