You are probably looking for `Promise.allSettled`[1]. Which, to be fair, becomes quite convulated with destructuring (note that the try-catch is not necessary anymore, since allSettled doesn't "throw"):

  // Parallel execution of independent operations
  const [
    { value: config, reason: configError },
    { value: userData, reason: userDataError },
  ] = await Promise.allSettled([
    readFile('config.json', 'utf8'),
    fetch('/api/user').then(r => r.json())
  ]);

  if (configError) {
    // Error with config
  }

  if (userDataError) {
    // Error with userData
  }
When dealing with multiple parallel tasks that I care about their errors individually, I prefer to start the promises first and then await for their results after all of them are started, that way I can use try catch or be more explicit about resources:

  // Parallel execution of independent operations
  const configPromise = readFile('config.json', 'utf8')
  const userDataPromise = fetch('/api/user').then(r => r.json())

  let config;
  try {
    config = await configPromise
  } catch (err) {
    // Error with config
  }

  let userData;
  try {
    userData = await userDataPromise
  } catch (err) {
    // Error with userData
  }
Edit: added examples for dealing with errors with allSettled

[1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...