Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Promise's second .then() not failing [duplicate]

I'm having trouble with chaining .then() calls for a promise. When executing the following code:

var prom = new Promise(function(resolve, reject) {
  //let's always fail
  reject(Error("buuuu!"));
});

var thenable = 
prom.then(
    function(done) {
        console.log("First handler: Done!: Argument: ", done);
        return "First then: DONE";
    },
    function(fail) {
        console.error("First handler: Fail!. Argument: ", fail);
        return "First then: FAIL";
    }
).then(
    function(done) {
        console.info("Second handler: Done!.  Argument: ", done);
    },
    function(fail) {
        console.error("Second handler: Fail!.  Argument: ", fail);
    }
);

This prints the following in the console:

First handler: Fail!. Argument:  Error {stack: (...), message: "buuuu!"}
Second handler: Done!.  Argument:  First then: FAIL


Why does the second then() has its done handler called instead of the fail one?

Is this a bug with Chrome? (Note that I'm only interested in Google Chrome's behavior)

Do I need to resort to returning pre-resolved/rejected Promises from the .then handlers?

like image 799
MrFusion Avatar asked Jan 29 '26 22:01

MrFusion


1 Answers

Why does the second then() has its done handler called instead of the fail one?

Because you handled the error in the first then() of the chain already, making the promise resolve with the "First then: FAIL" string that you returned from it.

Is this a bug with Chrome?

No, that's how promises are supposed to work.

Do I need to resort to returning pre-resolved/rejected Promises from the .then handlers?

You can do that, yes. Other ways to trigger the second fail handler would be:

  • Simply omit the first error handler:

    prom.then(function(done) {
        console.log("First handler: Done!: Argument: ", done);
        return "First then: DONE";
    }).then(function(done) {
        console.info("Second handler: Done!.  Argument: ", done);
    }, function(fail) {
        console.error("Second handler: Fail!.  Argument: ", fail);
    });
    
  • Or rethrow an exception (that's similar to returning a rejected promise):

    prom.then(function(done) {
        console.log("First handler: Done!: Argument: ", done);
        return "First then: DONE";
    }, function(fail) {
        console.error("First handler: Fail!. Argument: ", fail);
        throw new Error("First then: FAIL"); // or: throw fail;
        // alternatively, you can return a rejected promise:
        return Promise.reject(new Error("First then: FAIL"));
    }).then(function(done) {
        console.info("Second handler: Done!.  Argument: ", done);
    }, function(fail) {
        console.error("Second handler: Fail!.  Argument: ", fail);
    });
    
like image 177
Bergi Avatar answered Jan 31 '26 13:01

Bergi