Promise.all 사용 시 일부 실패 처리 패턴
문제 상황
대시보드 페이지에서 여러 통계 API를 동시에 호출하는 코드를 작성했다. Promise.all을 사용했는데, 한 API가 실패하면 전체 페이지가 에러 상태가 되는 문제가 발생했다.
const results = await Promise.all([
fetchUserStats(),
fetchSalesData(),
fetchTrafficData()
]);
통계 중 하나가 실패해도 나머지는 보여주는 게 사용자 경험상 더 나았다.
해결 방법
1. Promise.allSettled 폴리필
Node 10에서는 아직 지원하지 않아서 직접 구현했다.
const allSettled = promises =>
Promise.all(
promises.map(p =>
Promise.resolve(p)
.then(value => ({ status: 'fulfilled', value }))
.catch(reason => ({ status: 'rejected', reason }))
)
);
const results = await allSettled([
fetchUserStats(),
fetchSalesData(),
fetchTrafficData()
]);
const succeeded = results
.filter(r => r.status === 'fulfilled')
.map(r => r.value);
2. 기본값 제공
각 Promise를 catch로 감싸서 실패 시 기본값을 반환하도록 했다.
const [userStats, salesData, trafficData] = await Promise.all([
fetchUserStats().catch(() => null),
fetchSalesData().catch(() => ({ total: 0, items: [] })),
fetchTrafficData().catch(() => null)
]);
if (userStats) {
renderUserStats(userStats);
}
선택 기준
- 필수 데이터: Promise.all 사용, 하나라도 실패하면 에러 처리
- 선택 데이터: allSettled 패턴이나 catch로 기본값 제공
- 로깅 필요: allSettled로 실패 이유 기록
대시보드처럼 여러 독립적인 데이터를 보여주는 경우 두 번째 방식이 간단하고 실용적이었다.