Promise.all 오류 하나 때문에 전체가 실패하는 문제 해결

문제 상황

대시보드에서 여러 통계 API를 동시에 호출하는 기능을 구현했다. 초기에는 Promise.all로 간단하게 처리했는데, 한 API가 실패하면 전체가 실패해버리는 문제가 있었다.

const results = await Promise.all([
  fetchUserStats(),
  fetchSalesStats(),
  fetchTrafficStats()
]);

통계 중 하나가 일시적으로 오류가 나도 나머지는 보여줘야 하는 요구사항이었다.

해결 방법

각 Promise를 catch로 감싸서 에러를 값으로 변환하는 방식을 적용했다.

const safePromise = (promise) => {
  return promise
    .then(data => ({ success: true, data }))
    .catch(error => ({ success: false, error }));
};

const results = await Promise.all([
  safePromise(fetchUserStats()),
  safePromise(fetchSalesStats()),
  safePromise(fetchTrafficStats())
]);

const successData = results
  .filter(r => r.success)
  .map(r => r.data);

대안 고려

Promise.allSettled가 ES2020에 제안되어 있다고 하는데, 아직 사용 가능한 환경이 아니라 직접 구현했다. polyfill을 추가하는 것도 방법이지만, 간단한 wrapper로 충분했다.

결과

이제 일부 API가 실패해도 성공한 데이터는 화면에 표시된다. 실패한 항목은 에러 메시지를 보여주고, Sentry로 로그를 남겨 모니터링하고 있다.

병렬 처리의 장점은 유지하면서도 부분 실패를 graceful하게 처리할 수 있게 됐다.