Promise rejection unhandled 에러란 무엇인가?
🔗 관련 에러 해결 가이드
JavaScript 개발을 하다 보면 콘솔에서 ‘Promise rejection unhandled’ 또는 ‘UnhandledPromiseRejectionWarning’ 메시지를 자주 마주치게 됩니다. 이 에러는 Promise가 reject 되었지만 이를 처리하는 catch 블록이나 에러 핸들러가 없을 때 발생합니다. Node.js 환경에서는 경고로 표시되지만, 향후 버전에서는 프로세스를 종료시킬 수 있어 반드시 해결해야 하는 중요한 문제입니다. 특히 프로덕션 환경에서는 예상치 못한 서비스 중단을 일으킬 수 있어 개발 단계에서부터 철저히 관리해야 합니다.
🤖 AI 에러 분석 도우미
이 에러는 다음과 같은 상황에서 주로 발생합니다:
- 코드 문법 오류가 있을 때
- 라이브러리나 의존성 문제
- 환경 설정이 잘못된 경우
- 타입 불일치 문제
💡 위 해결법을 순서대로 시도해보세요. 90% 이상 해결됩니다!
에러 상세 분석
Promise rejection unhandled 에러는 비동기 작업의 실패를 적절히 처리하지 않았을 때 발생합니다. Promise 객체는 세 가지 상태를 가집니다: pending(대기), fulfilled(이행), rejected(거부). Promise가 rejected 상태로 전환되면 반드시 에러를 처리해야 하는데, 이를 누락하면 런타임에서 경고를 발생시킵니다.
브라우저 환경에서는 ‘unhandledrejection’ 이벤트가 발생하고, Node.js에서는 ‘unhandledRejection’ 이벤트가 발생합니다. 이 에러를 방치하면 메모리 누수, 예측 불가능한 동작, 디버깅 어려움 등의 문제가 발생할 수 있습니다. 최신 Node.js 버전에서는 처리되지 않은 Promise rejection이 발생하면 프로세스가 종료되도록 변경될 예정이므로, 모든 Promise 에러를 적절히 처리하는 것이 필수입니다.
발생 원인 5가지
1. catch 블록 누락
가장 흔한 원인으로, Promise 체인에서 catch 메서드를 추가하지 않은 경우입니다. 비동기 작업이 실패해도 에러를 잡을 방법이 없어 unhandled rejection이 발생합니다.
// 잘못된 예
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => console.log(data));
// 네트워크 에러 발생 시 처리되지 않음
2. async/await에서 try-catch 미사용
async 함수 내에서 await를 사용할 때 try-catch 블록으로 감싸지 않으면, 에러가 발생해도 처리되지 않습니다.
// 잘못된 예
async function fetchData() {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
return data;
}
3. Promise 체인 중간에 에러 발생
Promise 체인의 중간 단계에서 에러가 발생했지만, 마지막에 catch가 없거나 중간에 에러 처리가 누락된 경우입니다.
Promise.resolve()
.then(() => JSON.parse('잘못된 JSON'))
.then(data => console.log(data));
// JSON 파싱 에러가 처리되지 않음
4. 이벤트 핸들러 내부의 Promise
이벤트 리스너나 콜백 함수 내부에서 Promise를 반환하지만, 호출하는 쪽에서 에러를 처리하지 않는 경우입니다.
button.addEventListener('click', () => {
fetch('/api/data').then(res => res.json());
// 에러 처리 없음
});
5. Promise.all() 사용 시 개별 에러 미처리
여러 Promise를 동시에 실행할 때, 하나라도 reject되면 전체가 실패하는데 이를 처리하지 않은 경우입니다.
Promise.all([
fetch('/api/users'),
fetch('/api/posts'),
fetch('/api/comments')
]);
// 하나라도 실패하면 처리되지 않음
해결방법 7가지
1. catch 메서드 추가
Promise 체인의 마지막에 catch를 추가하여 모든 에러를 처리합니다.
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => {
console.error('에러 발생:', error);
// 에러 처리 로직
});
2. async/await와 try-catch 사용
async 함수에서는 try-catch 블록으로 에러를 처리합니다.
async function fetchData() {
try {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
return data;
} catch (error) {
console.error('데이터 가져오기 실패:', error);
throw error; // 또는 기본값 반환
}
}
3. 전역 에러 핸들러 설정
브라우저와 Node.js 환경 모두에서 전역 핸들러를 설정할 수 있습니다.
// 브라우저
window.addEventListener('unhandledrejection', event => {
console.error('처리되지 않은 Promise rejection:', event.reason);
event.preventDefault();
});
// Node.js
process.on('unhandledRejection', (reason, promise) => {
console.error('처리되지 않은 rejection:', reason);
// 로깅, 모니터링 등
});
4. Promise.allSettled() 사용
모든 Promise의 결과를 확인하고 싶을 때 사용합니다.
const results = await Promise.allSettled([
fetch('/api/users'),
fetch('/api/posts'),
fetch('/api/comments')
]);
results.forEach((result, index) => {
if (result.status === 'fulfilled') {
console.log(`요청 ${index} 성공:`, result.value);
} else {
console.error(`요청 ${index} 실패:`, result.reason);
}
});
5. finally 블록 활용
성공/실패 여부와 관계없이 실행되어야 할 코드를 처리합니다.
fetch('/api/data')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error))
.finally(() => {
console.log('요청 완료');
// 로딩 상태 해제 등
});
6. 에러 래퍼 함수 생성
반복적인 에러 처리를 위한 유틸리티 함수를 만듭니다.
async function safeAsync(fn) {
try {
return await fn();
} catch (error) {
console.error('에러 발생:', error);
return null; // 또는 기본값
}
}
// 사용
const data = await safeAsync(() => fetch('/api/data').then(r => r.json()));
7. ESLint 규칙 활용
코드 작성 단계에서 에러를 방지합니다.
// .eslintrc.js
module.exports = {
rules: {
'no-async-promise-executor': 'error',
'require-await': 'warn',
'no-return-await': 'error'
}
};
예방법과 베스트 프랙티스
1. 모든 Promise에 에러 처리 추가: Promise를 생성할 때마다 반드시 catch나 try-catch를 추가하는 습관을 들이세요.
2. 에러 로깅 시스템 구축: Sentry, LogRocket 같은 도구를 사용하여 프로덕션 환경의 에러를 모니터링하세요.
3. 타입스크립트 활용: Promise 타입을 명시하여 컴파일 단계에서 에러를 감지할 수 있습니다.
4. 코드 리뷰: Promise 사용 시 에러 처리 여부를 체크리스트에 포함시키세요.
5. 테스트 작성: 에러 케이스에 대한 단위 테스트를 작성하여 에러 처리가 제대로 되는지 검증하세요.
마무리
Promise rejection unhandled 에러는 JavaScript 개발에서 흔히 마주치는 문제이지만, 적절한 에러 처리만으로 쉽게 해결할 수 있습니다. 모든 비동기 작업에 catch나 try-catch를 추가하고, 전역 에러 핸들러를 설정하며, ESLint 같은 도구를 활용하면 대부분의 문제를 예방할 수 있습니다. 안정적인 애플리케이션을 위해 Promise 에러 처리를 철저히 하는 습관을 기르시기 바랍니다.
📚 함께 읽으면 좋은 글
Promise rejection unhandled 완벽 해결법 – 원인부터 예방까지
📅 2025. 11. 16.
🎯 Promise rejection unhandled
ReferenceError: variable is not defined 완벽 해결법 – 원인부터 예방까지
📅 2025. 11. 19.
🎯 ReferenceError: variable is not defined
SyntaxError: Unexpected token 완벽 해결 가이드 – JavaScript 에러 정복하기
📅 2025. 11. 18.
🎯 SyntaxError: Unexpected token
TypeError: Cannot set property of null 완벽 해결법 – 원인부터 예방까지
📅 2025. 11. 18.
🎯 TypeError: Cannot set property of null
ReferenceError: variable is not defined 완벽 해결 가이드 – JavaScript 에러 해결
📅 2025. 11. 16.
🎯 ReferenceError: variable is not defined
💡 위 글들을 통해 더 깊이 있는 정보를 얻어보세요!
📢 이 글이 도움되셨나요? 공유해주세요!
여러분의 공유 한 번이 더 많은 사람들에게 도움이 됩니다 ✨
🔥 공유할 때마다 블로그 성장에 큰 힘이 됩니다! 감사합니다 🙏
💬 여러분의 소중한 의견을 들려주세요!
이 글에서 가장 도움이 된 부분은 어떤 것인가요?
⭐ 모든 댓글은 24시간 내에 답변드리며, 여러분의 의견이 다른 독자들에게 큰 도움이 됩니다!
🎯 건설적인 의견과 경험 공유를 환영합니다 ✨
🔔 블로그 구독하고 최신 글을 받아보세요!
🌟 JavaScript 에러부터 다양한 실생활 정보까지!
매일 새로운 유용한 콘텐츠를 만나보세요 ✨
📧 RSS 구독 | 🔖 북마크 추가 | 📱 모바일 앱 알림 설정
지금 구독하고 놓치는 정보 없이 업데이트 받아보세요!