Promise.all과 에러 처리 전략
문제 상황
대시보드 화면에서 5개의 다른 API를 동시에 호출해서 데이터를 표시하는 기능을 구현했다. 초기에는 Promise.all을 사용해 간단히 처리했는데, 하나의 API가 실패하면 전체 화면이 에러 상태가 되는 문제가 발생했다.
const [users, orders, stats, notifications, config] = await Promise.all([
fetchUsers(),
fetchOrders(),
fetchStats(),
fetchNotifications(),
fetchConfig()
]);
통계 API가 타임아웃으로 실패하면 다른 정상 데이터도 모두 표시되지 않았다.
해결 방법
각 Promise를 catch로 감싸서 실패해도 기본값을 반환하도록 수정했다.
const fetchSafely = (promise, defaultValue) => {
return promise.catch(error => {
console.error('API call failed:', error);
return defaultValue;
});
};
const [users, orders, stats, notifications, config] = await Promise.all([
fetchSafely(fetchUsers(), []),
fetchSafely(fetchOrders(), []),
fetchSafely(fetchStats(), null),
fetchSafely(fetchNotifications(), []),
fetchSafely(fetchConfig(), {})
]);
이렇게 하면 일부 API가 실패해도 나머지는 정상적으로 표시된다. UI에서는 null이나 빈 배열일 때 "데이터를 불러올 수 없습니다" 메시지를 표시하도록 처리했다.
추가 고려사항
상황에 따라 Promise.allSettled를 사용하는 것도 방법이지만, 아직 Stage 3 proposal 단계라 프로덕션에서는 보류했다. Babel polyfill을 추가할 수도 있지만 간단한 래퍼 함수로도 충분했다.
에러 로깅은 Sentry로 전송해서 어떤 API가 자주 실패하는지 모니터링하고 있다.