0

Is there a way to provide a default errorCallback for a promise, such that the default errorCallback does not get called if user has provided an errorCallback.

function getFoo() {
    // TODO magic goes here to setup defaultErrorCallback as default
    return $http.get("/not_exists");
};

function defaultErrorCallback() { console.log("DDD"); }
function customCallback() { console.log("CCC"); }

getFoo().then(fooSuccess);
// output: DDD

getFoo().then(fooSuccess, customCallback);
// output: CCC
Ben George
  • 975
  • 3
  • 12
  • 23
  • Why do you want this? Normally you would just add `.catch(finalErrorCallback)` at the end of your promise chain, but it looks like you want the handler added inside `getFoo()` (which I do not think is possible). – gyre Mar 17 '17 at 05:55
  • This is kind of like asking, is there a way to have my code catch its own error, but only if nobody puts it inside a try-catch? That doesn't seem like a very sensible design. – JLRishe Mar 17 '17 at 05:58
  • @gyre - why ? mostly cause i have large code base that has many calls to this getFoo and don't want to repeat the getFoo().then(fooSuccess, defaultErrorCallback);. Our defaultErrorCallback requires injection of alertService, which is also annoying to have to inject everywhere just for this boilerplate code. – Ben George Mar 17 '17 at 06:24
  • What is alertService supposed to do? – gyre Mar 17 '17 at 06:29
  • Alert user of unexpected error, loging, stuff like that. By default there is default error message (90% of time), other times it is custom error message. – Ben George Mar 17 '17 at 06:44

3 Answers3

2

There is something of this in HTML 5.1's "uncaught promise rejection" mechanism, which dispatches an "uncaughtrejection" event for rejected promises that have no handlers at the time the promise was rejected. You add an event listener, get notified, process the rejection and cancel the event. You could also monitor "rejectionhandled" events for additional information. You will be, in effect, implementing you own HostPromiseRejectionTracker as outlined in section 25.4.1.9 of the ES7 standard (page 521 of the pdf) and it could get quite complicated, quite quickly.

There is nothing like this in Promise implementations which requires user code to add specific handlers for promise rejection, either as the second parameter of .then or first parameter of .catch (which is syntact sugar for the then method anyway). There are many ways of doing it explicitly but you can't supply a default rejection handler that is implicitly called if the user doesn't supply one.

Having said that note that "uncaughtrejection" events are not widely implemented in browsers and the specification may be subject to amendment before widespread adoption occurs.

traktor
  • 17,588
  • 4
  • 32
  • 53
1

I don't believe there is a way to do this for individual promises, but it is possible to override Angular's default error handling which as of Angular1.6 should only handle errors that are not caught elsewhere:

angular.
  module('exceptionOverwrite', []).
  factory('$exceptionHandler', ['alertService', function(alertService) {
    return function myExceptionHandler(exception, cause) {
      alertService.alertError(exception, cause);
    };
  }]);

If you want to add handling to specifically handle errors from getFoo(), you can have getFoo() inject some information into the error to make it identifiable:

function getFoo() {
    return $http.get("/not_exists")
        .catch(function (error) {
            error.errorSource = 'getFoo';
            throw error;
        });
}

// elsewhere...
angular.
  module('exceptionOverwrite', []).
  factory('$exceptionHandler', ['alertService', function(alertService) {
    return function myExceptionHandler(exception, cause) {
      if(exception.errorSource = 'getFoo') {
        alertService.alertError(exception, cause);
      } else {
        // default error handling
      }
    };
  }]);
JLRishe
  • 99,490
  • 19
  • 131
  • 169
0

Try creating wrapper around that like this -

Remember promise is chainable object.

function defaultCallback(){}
function okCallBack(){}
function getFoo(successCallback) {
    // TODO your $q magic goes here.
    var firstPromise = $http.get("/foo");
    var defaulErrorCallback=defaultCallback;
        if (typeof successCallback == 'function') {
          return firstPromise.then(successCallback).catch(defaulErrorCallback);

      }else{
         return firstPromise; 
      }
    };
getFoo(okCallBack);
Amit
  • 882
  • 6
  • 13