Concerning the error handling
I guess it depends on how you want to handle the errors that might occur. Do you have a concept for error handling in your code?
It might not be the best to simply "handle" the errors, while letting the getUserFriendsAndFriendOfFriend
pretend that it succeeded.
Personally, I would rather choose to let the error be thrown, and the consumer of your method should handle any possible errors.
Of course it could be that you want to log the errors that have occurred, but you should still re-throw it. If you do not, then the consumer cannot know if the method has failed or not?
How to stop the promises
Well, in your current version, you cannot really stop the promises, because they are all running already. You initiate all of them at the moment you are mapping the 2 arrays (this starts your internal fetch
).
The Promise.all
will then complete or fail in the end (though note, in your version of the code added to the question, you will only catch errors occurring on the friend_of_friend_IDs
array.
If you really want to make them fail as soon as the first one fails, then you can rather build a chain for them, by changing your code like:
await friendIDs
.concat( friend_of_friend_IDs )
.reduce(
(current, item) => current.then(
() => fetchJSON( `/users/${item}` ) ),
Promise.resolve( true ) );
this would first combine the 2 arrays, and then resolve in sequence the friends list. As soon as one would fail, the chain would stop, no other promises would be called anymore.
One problem with this approach would be that you wouldn't have the possibility to capture the results, but to do that you could theoretically just fill an array with the results, like for example in the following way:
let results = [];
return await friendIDs
.concat( friend_of_friend_IDs ) // concatenate the 2 arrays
.reduce( (current, item) => current.then( // chain the promise
() => fetchJSON( `/users/${item}` )
.then( response => results.push( response ) ) // handle the results
),
Promise.resolve( true ) ) // start with a default promise
.then( () => results ); // return the results
now the results
would contain all of the found friends, and that would be given out to the consumer of your method. Any errors that are fired, must be handled by the consumer, so the eventual code would look something like
async function getUserFriendsAndFriendOfFriend() {
let user = await fetchUser('/users/me');
let friendsIDs = await fetchJSON(`/friends/${user.id}`);
let friend_of_friend_IDs = await fetchJSON(`/friends_of_friends/${user.id}`);
let results = [];
return await friendIDs
.concat( friend_of_friend_IDs ) // concatenate the 2 arrays
.reduce( (current, item) => current.then( // chain the promise
() => fetchJSON( `/users/${item}` )
.then( response => results.push( response ) ) // handle the results
),
Promise.resolve( true ) ) // start with a default promise
.then( () => results ); // return the results
}
getUserFriendsAndFriendOfFriend()
.then( results => {
// results contains all the responses from the calls to fetchJSON with users id
})
.catch( err => {
// error will show you what went wrong with the single request, no other results will be returned
});