6
votes

I have recently been reading about async/await and using try and catch to handle promise rejections, and have been applying it to some of my old code.

I have the following:

async function() {
    try {
        await Promise.all([some functions]);
        doIfNoError();
    } catch (error) {
        console.log(error);
    }

The functions I am passing to Promise.all follow the form:

async function() {
    some code
    if (some condition) {
        return true
    } else {
        throw false
    }
 }

I intend that if any of the functions passed into Promise.all reject, the rejection is displayed. If none of the functions reject, then doIfNoError should fire. However, doIfNoError sometimes fires when it shouldn't, and I am given the error "Unhandled Promise Rejection".

3
maybe your doIfNoError function is doing some job that throws an error. Could you please add a real example here ?Raj Kumar
Also the function you are passing in Promise.all, try to pass a promise. It will either reject or resolve the promise and not just return or throw some value. eg: Promise.resolve(true) or Promise.reject(false)Raj Kumar
You must call your function and pass the resulting promises in the array to Promise.all, not the functions themselves.Bergi
Please post the actual code. Your try/catch code is fine, it must be either the calls or the contents of the async functions.Bergi
await Promise.all([some functions]) should be await Promise.all([some promises]);Mulan

3 Answers

5
votes

Actually, try/catch does work well with Promise.all().

Here is a snippet to prove it:

async function p1() {
  return 1;
}
async function boom() {
  throw new Error('boom');
}

// expected output: 'boom', ["value before Promise.all"]
async function asyncCall() {
  let all = ['value before Promise.all'];
  try {
    all = await Promise.all([p1(), boom()]);
  } catch(e) {
    console.log(e.message);
  }
  console.log(JSON.stringify(all));
}

asyncCall();
3
votes

Try using promises to their full potential, which includes a catch block for rejected promises. Note that if doIfNoError also throws an error, it will be caught with catch.

async function() {
    await Promise.all([some promises])
    .then(doIfNoError) // Promise.all resolved
    .catch(console.log) // Promise.all has at least one rejection
}

promiseAll = async (promises) => {
  await Promise.all(promises)
  .then(doIfNoError) // Promise.all resolved
  .catch(console.log) // Promise.all has at least one rejection
}
    
doIfNoError = () => console.log('No errors');

promiseAll([Promise.resolve(), 1, true, () => (false)]);
promiseAll([Promise.resolve(), 1, true, Promise.reject('rejected: because reasons'), Promise.resolve()]);
1
votes

1) throw false – this does not make sense, you should not throw a boolean but an instance of Error instead.

2) catch is only triggered when an error is thrown or the promise is "rejected" (note: reject and throw have the same effect with async-await). In contrast: "Resolving" a promise with a boolean value of false is not interpreted by async-await as an exception. So make sure you throw an error or reject the promise if you want the catch-block to kick in. if you reject, pass the exception as argument to reject, e.g. (Promise.reject(new Error("Something went wrong")).

Apart from what I mentioned above, your code looks fine.