We would like to reduce the number of catch blocks inside our promises. If we remove the nested catches, will exceptions bubble up to the parent catch?
temporaryUserModel.findOne({email: req.body.email}) .then(tempUser => { if (tempUser) { temporaryUserModel.findOneAndUpdate({_id: tempUser.toJSON()._id}, user) .then((doc) => { return res.status(200).json({ status: 'Success', data: {url: planOpted.chargifySignupUrl} }); }) .catch(err => error(err, res)); } else { temporaryUserModel(user).save() .then((doc) => { return res.status(200).json({ status: 'Success', data: {url: planOpted.chargifySignupUrl} }); }) .catch(err => error(err, res)); } }) .catch(err => error(err, res));
We'd like to remove the two nested catches and keep only the catch at the bottom. Is this ok?
In a promise nesting when you return a promise inside a then method, and if the returned promise is already resolved/rejected, it will immediately call the subsequent then/catch method, if not it will wait. If promised is not return, it will execute parallelly.
catch " around the executor automatically catches the error and turns it into rejected promise. This happens not only in the executor function, but in its handlers as well. If we throw inside a . then handler, that means a rejected promise, so the control jumps to the nearest error handler.
All that is needed is to mark your async function with the async keyword. This enables you to use the await keyword to resolve promises for you! The async/await mechanism for control flow is an extremely powerful way to reason about anything asynchronous within your app.
You cannot use try-catch statements to handle exceptions thrown asynchronously, as the function has "returned" before any exception is thrown. You should instead use the promise. then and promise. catch methods, which represent the asynchronous equivalent of the try-catch statement.
No, they won't. They only bubble up to the result promise if you chain your promises, for which you need to return
the inner promises created by the callbacks. Otherwise the outer promise cannot wait for them and will not know when/how they resolve (whether they fulfill or reject).
temporaryUserModel.findOne({email: req.body.email}).then(tempUser => { if (tempUser) { return temporaryUserModel.findOneAndUpdate({_id: tempUser.toJSON()._id}, user); // ^^^^^^ } else { return temporaryUserModel(user).save(); // ^^^^^^ } }).then((doc) => { // no need to duplicate this code when you chain anyway return res.status(200).json({ status: 'Success', data: {url: planOpted.chargifySignupUrl} }); }).catch(err => error(err, res));
You can extract some of the logic into separate functions, and return
the inner promises to bubble up any exceptions to the promise chain:
temporaryUserModel.findOne({email: req.body.email}) .then(updateTempUser) .then(formatResponse) .catch(err => error(err, res)); function updateTempUser(tempUser) { if (tempUser) { return temporaryUserModel.findOneAndUpdate({ _id: tempUser.toJSON()._id }, user); } else { return temporaryUserModel(user).save() } } function formatResponse(doc) { return res.status(200).json({ status: 'Success', data: {url: planOpted.chargifySignupUrl} }); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With