Promise.all is just wrapping up whatever promises you give it - so there's no reason you couldn't handle the errors separately for each one. For example, you could create a separate function for each of the fetches - you could even throw a custom error here that dictates some sort of "followUp" action to do, or identifies where the error is from, or anything (you can throw anything in javascript):
const fetchFromApi1 = async () => {
  try {
    const response = await fetch(api1);
    return response.json();
  } catch (err) {
    console.log('API 1 failed');
    
    // Throw a custom error
    throw {
      errorSource: 'API_CALL_1',
      message: 'API call 1 failed',
    };
  }
};
const fetchFromApi2 = async () => {
  // ----- 8< -----
};
Then you can just combine them in your your Promise.all - if you've thrown a custom error as above, you can use that to work out what to do:
const fetchAllTheThings = async () => {
  try {
    const [response1, response2] = await Promise.all([
      fetchFromApi1(),
      fetchFromApi2(),
    ]);
  } catch (err) {
    const { errorSource, message } = err;
    // do something....
  }
};
Edit
If you want to know which promise failed at the point of calling, you're probably better off using allSettled -
const fetchAllTheThings = async () => {
  const [result1, result2] = await Promise.allSettled([
    fetchFromApi1(),
    fetchFromApi2(),
  ]);
  if (result1.status === 'rejected') {
    // Sad for promise 1
  }
  if (result2.status === 'rejected') {
    // Sad for promise 2
  }
};