3

I have the following code that uses native promises:

function getUser() {
    return new Promise(function (resolve, reject) {
        reject();
    });
}

function changeUser() {
    return new Promise(function (resolve, reject) {
        return getUser().catch(function (responseData, test) {
            console.log('boo error'); // this logs `boo error`
            throw {};
        });
    });
}

changeUser().then(function () {
    console.log('done');
}).catch(function () {
    console.log('error'); // this is not triggered
});

When I run it, the lst catch block with console.log('error'); is not executed. Why is that? Is the implementation of native promises different from Q?

Max Koretskyi
  • 101,079
  • 60
  • 333
  • 488

2 Answers2

3

Because you never reject the promise you return from changeUser. You're only throwing within the chain of the promise returned from getUser, which cascades within that chain, but doesn't influence the new Promise constructed in changeUser.

Either:

return new Promise(function (resolve, reject) {
    return getUser().then(resolve, function (responseData, test) {
        console.log('boo error'); // this logs `boo error`
        reject();
    });
});

Or:

function changeUser() {
    return getUser().catch(function (responseData, test) {
        console.log('boo error'); // this logs `boo error`
        throw {};
    });
}
deceze
  • 510,633
  • 85
  • 743
  • 889
  • but isn't the promise returned by `getUser().then(` becomes the promise returned by `new Promise` as happens using `Q` library? – Max Koretskyi Nov 02 '16 at 10:22
  • Nope, the ECMAScript standard Promise implementation does not specify for the executor to be able to return anything. You can "renew the chain" within a `then`, not within the constructor. http://www.ecma-international.org/ecma-262/6.0/#sec-promise-executor – deceze Nov 02 '16 at 10:28
  • thanks, so the behavior [this answer](http://stackoverflow.com/a/27716590/2545680) talks about _the next then clause will be the then clause of the promise the function returned,_ is not applicable to executors, only to `then` methods? – Max Koretskyi Nov 02 '16 at 10:37
  • It pretty explicitly talks about what's going on in the `.then` handler, yes. – deceze Nov 02 '16 at 10:43
  • thanks, so there is no way to chain/merge two promise constructors without using `resolve` or `reject` callbacks? – Max Koretskyi Nov 02 '16 at 10:51
  • 1
    Mostly it doesn't make a whole lot of sense. If all you're doing from the executor is to return a different promise, why are you instantiating a `new Promise` to begin with…? – deceze Nov 02 '16 at 10:56
2

Because you're nesting two different promise chains in the changeUser function. The resolve and reject functions are never called in that function, thus the throw {} does not bubble up. If you execute this in Chrome you'll also get a 'Uncaught promise' message in the console.

Either fix it by:

return new Promise(function (resolve, reject) {
    return getUser().catch(function (responseData, test) {
        console.log('boo error'); // this logs `boo error`
        throw {};
    }).then(resolve, reject);
});

Or by removing the return new Promise line altogether.

Jan Jongboom
  • 26,598
  • 9
  • 83
  • 120