backbone.js - Catching Backbone sync errors -


i needed catch possible login page in responses server, have overridden backbone.sync globally can check 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 can call if user logs in     originalsuccess = options.success;     // proxy error callback first check if login page     originalerror = options.error;     options.error = function (model, xhr, options) {         if (xhr.status === 200 && xhr.responsetext === "") {             // parse error 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 new window relogon.html trigger new login                 window.showmodaldialog("../relogon.html");             } else {                 // normal error, pass along                  if (originalerror) {                     originalerror(model, xhr, options);                 }             }         }     };      // call original sync     backbone.originalsync(method, model, options); }; 

this broke miserably when going 0.9.9 1.0. looks original backbone.sync wraps error handlers differently, causing error handler called first, jquery xhr signature. had change signature of error handler this:

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

ok works, feeling doing wrong.

is there better way this?

i tried jquery promises need able switch error state success (when calling originalsuccess), did not seem work promises.

you can build own jquery deferred object alter default backbone.sync behavior

backbone.sync = function (method, model, opts) {     var xhr, dfd;      dfd = $.deferred();      // opts.success , opts.error resolved against deferred object     // instead of jqxhr object     if (opts)         dfd.then(opts.success, opts.error);      xhr = backbone.originalsync(method, model, _.omit(opts, 'success', 'error'));      // success : forward deferred     xhr.done(dfd.resolve);      // failure : resolve or reject deferred according cases     xhr.fail(function() {         if (xhr.status === 200 && xhr.responsetext === "") {             dfd.resolve.apply(xhr, arguments);         } else {             if (xhr.status === 200 || xhr.status === 302 || xhr.status === 0) {                 console.log('login');             }             dfd.reject.apply(xhr, arguments);         }     });      // return promise add callbacks if necessary     return dfd.promise(); }; 

the promise reflects end state choose.

http://jsfiddle.net/asmyq/4/ fail demo, http://jsfiddle.net/asmyq/5/ success.

and if may

  • you should not tie tightly backbone.sync login handling. use events, backbone or jquery.ajaxerror @andrey suggested
  • your server response should indicate authorization failure, 401 status
  • don't forget return deferred promise/jqxhr object when override sync, might come in handy down line

Comments

Popular posts from this blog

linux - xterm copying to CLIPBOARD using copy-selection causes automatic updating of CLIPBOARD upon mouse selection -

c++ - qgraphicsview horizontal scrolling always has a vertical delta -