0

I am using durandal.. I have a base controller that manage the calls to the server... every controller, specialized per use case, use the base controller to do the call to the server. In the base controller I have this code:

self.call = function (url, type, data, success) {
    return Q.when(
        $.ajax({
            ...
            error: function (jqXHR, textStatus, errorThrown) {
                if (jqXHR.status == 500) {
                   // Do some work
                }
            }
        })
     );

Then, in my specialized controller I have

myController.execute(command)
      .then(function () {
            //Do work ok
       })
        .fail(function (data) {
             //Manage error
       });

the execute method, internally call the call method I wrote at the start... The problem of this solution is that when I manage the error in the base controller, then I execute also the fail code in the specialized controller...

Another way I tried... in the base controller

self.call = function (url, type, data, success) {
    return Q.fail(function (jqXHR, textStatus, errorThrown) {
        if (jqXHR.status == 500) {
             app.showError("a new error");
        }
         else 
             throw { "jqXHR": jqXHR, "textStatus": textStatus, "errorThrown": errorThrown };
    });

In this case, the then code is executed in the specialized controller. How can I avoid to stop the propagation of the promise in this case?

Thank you

Matthew James Davis
  • 12,134
  • 7
  • 61
  • 90
Simone
  • 2,304
  • 6
  • 30
  • 79

1 Answers1

0

Instead of doing this:

myController.execute(command)
      .then(function () {
            //Do work ok
       })
        .fail(function (data) {
             //Manage error
       });

You should do this:

myController.execute(command)
      .then(function (data) {
            //Do work ok
       }, function (reason) {
            //error handled 
            //you need to manully throw error here if you want the error to be propagated
            //throw reason; 
       });

UPDATE You don't have to wrap jquery promise with q, here's another approach:

self.call = function (url, type, data, success) {
  var result = Q.defer();

  $.ajax({
     success: function (data) {
        result.resolve(data);
     },
     error: function (jqXHR, textStatus, errorThrown) {
       if (jqXHR.status == 500) {
          console.log('error 500, handled');
       } else {
          result.reject(textStatus);
       }
    }
  });

  return result;
}

This way you may "propagate" you error conditionally, though I wouldn't recommend this, because pending promises (neither resolved or rejected) may be a potential source of memory leaks.

Dziamid
  • 11,225
  • 12
  • 69
  • 104
  • No... I think I haven't been clear in explaining my problem.. someone also changed the title that I think is now wrong... I have a centralized point where I manage the call to server... If I obtain an error 500 I want to manage the error in this point, that is centralized (when I do `Q.when` or `Q.fail`) .... In all other cases, I want to propagate the error in the `fail` of `myController`.... To be more clear... I want to go in the `fail` or in the `function(reason)` of `myController` just when it's not an error 500 – Simone Apr 15 '15 at 08:19
  • Are you aware that you can set up a global jQuery ajax error handler? You can have local error handlers and rethrow anything you don't want to process in the local handler. – Peter Wone Apr 15 '15 at 14:35