Bluebird Monkey Goals: Catch with Result

In order for this question to be useful to as many people as possible, I would exclude my specific implementation details, in addition to using the Bluebird promise library with Node + Express below.

So, let's say that I have the following chain (where P returns the promise and res is the express HTTP response object):

 P().then(function(){ // do nothing if all went well (for now) // we only care if there is an error }).catch(function(error){ res.status(500).send("An error occurred"); }).then(function(){ return P(); }).then(function(pVal1){ return [pVal1, P()]; }) // TODO: catch an error from P() here and log pVal1 .spread(function(pVal1, pVal2){ if(pVal1 === pVal2) { console.log("Success!"); } else { console.log("Failure"); } }); 

Where I posted a TODO comment above, where I would like to catch an error that could occur from my call to P If I catch an error, I would like to register pVal1 , and then send a 500 error, as is done in the first catch. However, I'm not sure if this is possible with the way I structure my chain.

I think I need to do a fork, but I don’t think I understand this concept well enough to stop the asynchronous nature of JavaScript in order to get the best out of me! As such, any help is fully appreciated.

+6
source share
2 answers

Remember to catch errors at the end of the chain. This is also the place to send a response.

Mid-chain capture errors for intermittent error handling; the chain continues to work, so do not submit a response yet.

Here are some things to try:

 // example middleware function handle(req, res, next) { log("----------------"); return async("p1", "foo").then(function (pVal1) { return pVal1; }).then(function (pVal1) { var p2a = async("p2a", "bar"), p2b = async("p2a", "bar").catch(function (error) { log("Logging: " + error + " (pVal1 " + pVal1 + ")"); }); return [p2a, p2b]; }).spread(function (pVal1, pVal2) { if (pVal1 === pVal2) { res.send("Success!"); } else { res.send("Failure"); } }).catch(function (error) { res.status(500).send("An error occurred"); log("Logging: " + error); }); } // --------------------------------------------------------------------- // mockup response object var res = { status: function (code) { log("Sending status: " + code); return this; }, send: function () { log("Sending response: " + [].join.call(arguments, " ")); return this; } }; // mockup promise generator function async(name, value) { return new P(function (resolve, reject) { if ( confirm("let " + name + " succeed?") ) { log(name + " succeeds..."); resolve(value); } else { log(name + " fails..."); reject(name + " has failed"); } }); } function log() { var msg = document.createElement("DIV"); msg.textContent = [].join.call(arguments, " "); document.getElementById("log").appendChild(msg) document.body.scrollTop = document.body.scrollHeight; } 
 button { position: fixed; top: 5px; } 
 <script src="http://cdnjs.cloudflare.com/ajax/libs/bluebird/2.9.33/bluebird.min.js"></script> <button onclick="handle(null, res, null)">Go</button> <div id="log"></div> 
+2
source

This is possible if you use an explicit Promise.all instead of returning an array in .spread .

 }).then(function(pVal1){ // this becomes a `Promise.all` - the aggregation is explicit var all = Promise.all([pVal1, P()]); all.catch(function(e){ // "branching", we both return and `catch` the promise console.log("Error, pVal1 is", pVal1); }); return all; // return it }).spread(function(pVal1, pVal2){ // .... }); 
+1
source

All Articles