Reputation: 3356
I have the next function in my code that can interrupt execution due to several reasons:
const getAndCheckItem = async (itemId) => {
try {
const item = await getItem(itemId);
if(item.firstFail) {
throw "First fail";
}
if(item.secondFail) {
throw "Second fail";
}
if(notGood(item)) {
throw "Third fail";
}
return item;
}
catch(err) {
return Promise.reject(err);
}
};
If I call it inside some other async function in the following way, everything is fine and any internal throw is handled:
try {
item = await getAndCheckItem(ids[0]);
}
catch(err) {
// handle error
}
However, when I call the function for several ids:
try {
items = await Promise.all([ids.map(value => getAndCheckItem(value))]);
}
catch(err) {
// handle error
}
I receive unhandled promise reject in case of any internal throw. I understand that Promise.all() considers any returned non-promise value as a resolved promise. However, Promise.reject(err)
should return a Promise and thus be handled. What's the problem?
Upvotes: 0
Views: 273
Reputation: 371193
Promise.all() considers any returned non-promise value as a resolved promise.
Sure, but when you do
return Promise.reject(err);
you're returning a Promise, so once it gets unwrapped by the caller, the getAndCheckItem
call results in a rejected Promise. Doing return Promise.reject(err)
is very similar to doing throw err
inside something async
.
If all you do in a catch
is re-throw or return a rejected Promise, there's not much point to it - you may as well leave that part off completely, and just let the caller handle it:
const getAndCheckItem = async (itemId) => {
const item = await getItem(itemId);
if(item.firstFail) {
throw "First fail";
}
if(item.secondFail) {
throw "Second fail";
}
if(notGood(item)) {
throw "Third fail";
}
return item;
}
You're also currently passing an array of arrays of Promises to Promise.all
:
await Promise.all([ids.map(value => getAndCheckItem(value))]);
In which case the Promise.all
won't really do anything, since the only item of its array is a non-Promise (another array). If any of the inner promises reject, they won't be handled, so you'll get an unhandled rejection.
Instead, pass an array of Promises to Promise.all
:
await Promise.all(ids.map(value => getAndCheckItem(value)));
Or, more concisely:
await Promise.all(ids.map(getAndCheckItem));
Upvotes: 2