Angular $q catch block resolves promis?

Viewed 3289

The past view days I read a lot of best practices in handling with promises. One central point of the most postings where something like this:

So if you are writing that word [deferred] in your code [...], you are doing something wrong.1

During experimenting with the error handling I saw an for me unexpected behavior. When I chain the promises and It run into the first catch block the second promise gets resolved and not rejected.

Questions

  • Is this a normal behavior in other libs / standards (e.g. q, es6), too and a caught error counts as solved like in try / catch?
  • How to reject the promise in the catch block so that the second gets, called with the same error / response object?

Example

In this example you see 'I am here but It was an error'

Full Plunker

function BaseService($http, $q) {
  this.$http = $http;
  this.$q = $q;
}

BaseService.prototype.doRequest = function doRequest() {
  return this.$http({
      method: 'GET',
      url: 'not/exisint/url'
    })
    .then(function (response) {
      // do some basic stuff
    })
    .catch(function(response) {
      // do some baisc stuff e.g. hide spinner
    });
}


function ChildService($http, $q) {
  this.$http = $http;
  this.$q = $q;
}

ChildService.prototype = Object.create(BaseService.prototype);

ChildService.prototype.specialRequest = function specialRequest() {
  return this.doRequest()
    .then(function (response)  {
      alert('I am here but It was an error');
    })
    .catch(function (response) {
      // do some more specific stuff here and
      // provide e.g. error message
      alert('I am here but It was an error');
      return response;
    });
}

Workaround:

With this workaround you can solve this problem, but you have to create a new defer.

BaseService.prototype.doRequest = function doRequest() {
  var dfd = this.$q.defer();

  return this.$http({
      method: 'GET',
      url: 'not/exisint/url'
    })
    .then(function (response) {
      // do some basic stuff
      dfd.resolve(response);
    })
    .catch(function(response) {
      // do some basic stuff e.g. hide spinner
      dfd.reject(error);
    });
}
2 Answers
Related