Promise.all 병렬 처리 시 에러 핸들링 개선

문제 상황

관리자 대시보드에서 5개의 통계 API를 동시에 호출하는 코드를 작성했다. Promise.all을 사용했는데, 간헐적으로 하나의 API가 타임아웃되면 전체 대시보드가 로딩 실패로 표시되는 문제가 발생했다.

const loadDashboard = async () => {
  try {
    const [users, orders, revenue, traffic, conversion] = await Promise.all([
      fetchUsers(),
      fetchOrders(),
      fetchRevenue(),
      fetchTraffic(),
      fetchConversion()
    ]);
  } catch (error) {
    // 하나라도 실패하면 여기로
    showError('데이터 로딩 실패');
  }
};

해결 방법

Promise.allSettled는 아직 Stage 3 제안이라 프로덕션에서 사용할 수 없었다. 대신 각 Promise를 catch로 감싸서 항상 fulfilled 상태로 만드는 패턴을 적용했다.

const safePromise = (promise, fallback) => {
  return promise.catch(error => {
    console.error(error);
    return fallback;
  });
};

const loadDashboard = async () => {
  const [users, orders, revenue, traffic, conversion] = await Promise.all([
    safePromise(fetchUsers(), []),
    safePromise(fetchOrders(), []),
    safePromise(fetchRevenue(), { total: 0 }),
    safePromise(fetchTraffic(), null),
    safePromise(fetchConversion(), null)
  ]);

  // 각 데이터를 개별적으로 처리
  if (users.length > 0) renderUsers(users);
  if (revenue.total > 0) renderRevenue(revenue);
};

결과

일부 API가 실패해도 나머지 데이터는 정상적으로 표시되도록 개선했다. 사용자는 부분적으로라도 정보를 확인할 수 있게 되었고, 에러 로그를 통해 어떤 API가 문제인지 추적할 수 있게 되었다.

추후 브라우저 지원이 확대되면 Promise.allSettled로 마이그레이션할 예정이다.