Reputation: 1485
i have simple validation promises in my code which i execute like so
inBlacklist(address)
.then(isUsed(payments))
.then(isProcessed(ref_num))
.then(validateType(type))
.catch((err) => {
console.log(err);
return res.status(400).send({ message: err.message });
});
Which basically checks if the payment is propertly processed or not.
Here are the promises
export const isUsed = (payments) =>
new Promise((resolve, reject) => {
if (payments) {
const paymentsData = payments.map((i) => {
i.date = moment(i.date).startOf('minute').format('YYYY-MM-DD HH:mm');
i.amount = parseInt(i.amount);
return i;
});
Transaction.findOne(paymentsData)
.exec()
.then((data) => {
if (data.length) {
reject({ message: 'Payment is already used', status: 409 });
} else {
resolve(false);
}
})
.catch((err) => {
reject(err);
});
}
});
export const inBlacklist = (address) =>
new Promise((resolve, reject) => {
Blacklist.exists({ blocked: true, address })
.then((blocked) => {
if (blocked) {
return reject({ message: 'Address is in blacklist', status: 406 });
} else {
return resolve(false);
}
})
.catch((err) => {
return reject(err);
});
});
export const isProcessed = (ref_num) =>
new Promise((resolve, reject) => {
if (ref_num) {
Transaction.exists({ ref_num, status: { $in: ['processing', 'expired', 'resolved'] } })
.exec()
.then((data) => {
return reject({ message: 'Payment is already used', status: 422 });
})
.catch((err) => {
reject(err);
});
} else {
return resolve(false);
}
});
export const validateType = (type) =>
new Promise((resolve, reject) => {
const validTypes = ['bitcoin', 'dash'];
if (validTypes.includes(type)) {
return resolve();
} else {
return reject({ message: 'Invalid crypto type', status: 422 });
}
});
Now when i call the chain, it only works in case when inBlacklist
was rejected. For the others it appears as an unhandled error, which just shows up on console and doesnt return the response for api.
I have also tried this
Promise.all([inBlacklist(address), isUsed(payments), isProcessed(ref_num), validateType(type)]).catch((err) => {
return res.status(err.status || 400).send({ message: err.message });
});
Which works fine, but what if i want to use the first variant? Why i cant catch all the promise rejections in one .catch block?
Upvotes: 0
Views: 1400
Reputation: 331
Looks like the issue is that isUsed
is being executed immediately rather than after inBlacklist
resolves, so your .then()
is being given a Promise object rather than a callback function. It's just like if you wrote a(b(c));
, b
is executed first and then the return value is passed to a
.
Instead, you want to pass to .then
a callback function that executes the next function, so try using arrow functions inside the then
s, like so:
inBlacklist(address)
.then(() => isUsed(payments))
.then(() => isProcessed(ref_num))
.then(() => validateType(type))
.catch((err) => {
console.log(err);
return res.status(400).send({ message: err.message });
});
Upvotes: 1