Adi
Adi3y ago

✅ – Adi – 08-24 Jun 22

I am making async calls inside forEach but if some calls in foreach fail then it is not running the forEach block on remaining elements. I have already wrapped forEach inside try/catch block but did not work. I used try/catch inside forEach and then it worked. code:
subs.forEach(async subscription => {
try {
const endpoint = subscription.endpoint;
const id = endpoint.substr((endpoint.length - 8), endpoint.length);
const result = await webpush.sendNotification(subscription, notificationPayload, options);
console.log(`Endpoint ID: ${id}`);
console.log(`Result: ${result.statusCode}`);
} catch (error) {
console.error("send notification error:", error)
}
});
subs.forEach(async subscription => {
try {
const endpoint = subscription.endpoint;
const id = endpoint.substr((endpoint.length - 8), endpoint.length);
const result = await webpush.sendNotification(subscription, notificationPayload, options);
console.log(`Endpoint ID: ${id}`);
console.log(`Result: ${result.statusCode}`);
} catch (error) {
console.error("send notification error:", error)
}
});
By default forEach should not return early if any async call fails is that correct? then why in above case I have to use try/catch inside forEach??
4 Replies
ScriptyChris
ScriptyChris3y ago
you tried using try..catch outside forEach? how? try..catch works for sync code. If you have async code you should use await to "make it" sync, so a promise returned by async code is "awaited"/resolved and if it throws then try..catch can handle it. In case of forEach, it executes your async code, but doesn't wait each iteration to finish, because the logic inside forEach doesn't await the callback your provide - it just executes it, ignores immediately returned promise (by async function). Hence, forEach returns undefined before your async code gets executed (including awaits inside the callback). If you had sync code inside forEach then try..catch would work, because sync code isn't wrapped in promise as with async functions Possible solution is to change forEach to map - which will return array of promises - and put it inside Promise.all, which can be awaited and this can be handled by try..catch
Adi
AdiOP3y ago
If you had sync code inside forEach then try..catch would work, because sync code isn't wrapped in promise as with async functions
Agree In my case I want to delete subscriptions i.e call delete API when subscription fails. So should I do that in catch block or first collect all the failed subscriptions and then delete them one by one?? what do you suggest?
ScriptyChris
ScriptyChris3y ago
if you want to delete failed subscriptions then i think you can use Promise.allSettled() instead of Promise.all() and then check status of each promise - for every failed one, delete it (your catch logic) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled
reactibot
reactibot3y ago
This question has an answer! Thank you for helping 😄 If you have a followup question, you may want to reply to this thread so other members know they're related. https://discord.com/channels/102860784329052160/565213527673929729/989083488475054081 This thread hasn’t had any activity in 12 hours, so it’s now locked. Threads are closed automatically after 12 hours. If you have a followup question, you may want to reply to this thread so other members know they're related. https://discord.com/channels/102860784329052160/565213527673929729/989083488475054081