Promise rejection unhandled 에러 완벽 해결 가이드
JavaScript 개발 중 Promise rejection unhandled 에러를 마주친 적이 있으신가요? 이 에러는 비동기 처리 과정에서 Promise가 거부(reject)되었지만 이를 적절히 처리하지 않았을 때 발생합니다. Node.js 환경에서는 “UnhandledPromiseRejectionWarning”으로, 브라우저에서는 “Unhandled Promise Rejection”으로 표시됩니다. 이 에러를 방치하면 애플리케이션의 안정성이 저하되고, Node.js 15 이상 버전에서는 프로세스가 강제 종료될 수 있습니다. 본 가이드에서는 Promise rejection unhandled 에러의 원인부터 해결법, 예방 전략까지 상세히 다룹니다.
🤖 AI 에러 분석 도우미
이 에러는 다음과 같은 상황에서 주로 발생합니다:
- 코드 문법 오류가 있을 때
- 라이브러리나 의존성 문제
- 환경 설정이 잘못된 경우
- 타입 불일치 문제
💡 위 해결법을 순서대로 시도해보세요. 90% 이상 해결됩니다!
에러 상세 분석
🔗 관련 에러 해결 가이드
Promise rejection unhandled 에러는 Promise 체인에서 reject된 상태를 catch하지 않았을 때 발생하는 경고입니다. Promise는 세 가지 상태를 가집니다: pending(대기), fulfilled(이행), rejected(거부). rejected 상태가 되었을 때 .catch() 핸들러나 try-catch 블록으로 처리하지 않으면 이 에러가 발생합니다.
Node.js에서는 다음과 같은 경고 메시지를 표시합니다:
(node:12345) UnhandledPromiseRejectionWarning: Unhandled promise rejection.
(node:12345) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch().
브라우저 콘솔에서는 “Uncaught (in promise) Error” 형태로 표시되며, 개발자 도구에서 에러 스택을 확인할 수 있습니다. 이 에러는 코드 실행을 즉시 중단시키지는 않지만, 예상치 못한 동작을 유발하고 디버깅을 어렵게 만듭니다.
발생 원인 5가지
1. catch 블록 누락
가장 흔한 원인은 Promise 체인에서 .catch() 메서드를 빠뜨리는 것입니다. 비동기 작업이 실패할 가능성을 간과하고 에러 처리 로직을 작성하지 않은 경우입니다.
// 잘못된 예
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.all() 에러 처리 부재
여러 Promise를 동시에 실행할 때 하나라도 실패하면 전체가 reject되는데, 이를 처리하지 않는 경우입니다.
// 잘못된 예
Promise.all([
fetch('/api/users'),
fetch('/api/posts'),
fetch('/api/comments')
]).then(responses => console.log(responses));
4. 이벤트 핸들러 내 비동기 에러
이벤트 리스너나 콜백 함수 내에서 발생한 Promise 에러는 외부에서 catch할 수 없습니다.
// 잘못된 예
button.addEventListener('click', async () => {
const data = await fetchData(); // 에러 발생 시 처리 안 됨
});
5. 체인 중간에서 에러 발생
Promise 체인 중간에서 에러가 발생했지만 마지막에만 catch를 두어 중간 에러를 놓치는 경우입니다.
// 잘못된 예
getUser()
.then(user => processData(user)) // 여기서 에러 발생 가능
.then(result => saveToDatabase(result));
해결방법 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 with 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);
return null; // 기본값 반환
}
}
방법 3: Promise.all() 에러 처리
Promise.all()에 catch를 추가하거나 Promise.allSettled()를 사용합니다.
// 방법 1: catch 추가
Promise.all([
fetch('/api/users'),
fetch('/api/posts')
])
.then(responses => console.log(responses))
.catch(error => console.error('일부 요청 실패:', error));
// 방법 2: allSettled 사용
Promise.allSettled([
fetch('/api/users'),
fetch('/api/posts')
])
.then(results => {
results.forEach((result, index) => {
if (result.status === 'rejected') {
console.error(`요청 ${index} 실패:`, result.reason);
}
});
});
방법 4: 전역 에러 핸들러 설정
처리되지 않은 Promise rejection을 전역에서 포착합니다.
// Node.js
process.on('unhandledRejection', (reason, promise) => {
console.error('처리되지 않은 Rejection:', promise, '이유:', reason);
// 로깅, 알림 전송 등
});
// 브라우저
window.addEventListener('unhandledrejection', event => {
console.error('처리되지 않은 Promise rejection:', event.reason);
event.preventDefault(); // 기본 에러 출력 방지
});
방법 5: 에러 래핑 함수 사용
재사용 가능한 에러 처리 유틸리티를 만듭니다.
const handleAsync = (fn) => {
return function(...args) {
return fn(...args).catch(error => {
console.error('에러 발생:', error);
throw error; // 또는 처리 후 반환
});
};
};
// 사용 예
const safeFetchData = handleAsync(async (url) => {
const response = await fetch(url);
return await response.json();
});
방법 6: finally 블록 활용
성공/실패 여부와 관계없이 실행할 코드를 finally에 작성합니다.
fetchData()
.then(data => processData(data))
.catch(error => console.error('에러:', error))
.finally(() => {
console.log('작업 완료');
hideLoadingSpinner();
});
방법 7: 명시적 Promise 반환
함수에서 Promise를 반환할 때 명시적으로 에러를 처리합니다.
function getUserData(userId) {
return fetch(`/api/users/${userId}`)
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
})
.catch(error => {
console.error('사용자 데이터 로딩 실패:', error);
return { error: true, message: error.message };
});
}
예방법과 베스트 프랙티스
1. 모든 Promise에 에러 핸들러 추가: Promise를 생성할 때마다 .catch()나 try-catch를 필수로 작성하는 습관을 들이세요.
2. ESLint 규칙 활용: ‘no-floating-promises’ 또는 ‘require-await’ 규칙을 설정하여 처리되지 않은 Promise를 자동으로 감지합니다.
// .eslintrc.js
module.exports = {
rules: {
'no-floating-promises': 'error'
}
};
3. TypeScript 사용: TypeScript의 타입 시스템을 활용하면 Promise 반환 타입을 명시적으로 관리할 수 있습니다.
4. 에러 로깅 시스템 구축: Sentry, LogRocket 같은 도구를 사용하여 프로덕션 환경의 처리되지 않은 에러를 모니터링합니다.
5. 코드 리뷰 체크리스트: PR 리뷰 시 비동기 코드의 에러 처리 여부를 필수 체크 항목으로 포함시킵니다.
마무리
Promise rejection unhandled 에러는 JavaScript 비동기 프로그래밍에서 흔히 발생하지만, 적절한 에러 처리 패턴을 적용하면 쉽게 해결할 수 있습니다. .catch() 메서드, try-catch 블록, 전역 에러 핸들러를 적절히 조합하여 사용하세요. 무엇보다 중요한 것은 “모든 Promise는 반드시 처리되어야 한다”는 원칙을 지키는 것입니다. 이 가이드의 해결법과 베스트 프랙티스를 적용하면 안정적이고 유지보수하기 쉬운 비동기 코드를 작성할 수 있습니다. 지금 바로 여러분의 프로젝트에 적용해보세요!
📚 함께 읽으면 좋은 글
Promise rejection unhandled 완벽 해결법 – 원인부터 예방까지
📅 2025. 10. 6.
🎯 Promise rejection unhandled
Promise rejection unhandled 완벽 해결법 – 원인부터 예방까지
📅 2025. 10. 6.
🎯 Promise rejection unhandled
ReferenceError: variable is not defined 완벽 해결법 – 원인부터 예방까지
📅 2025. 10. 24.
🎯 ReferenceError: variable is not defined
Memory leak in JavaScript applications 완벽 해결법 – 원인부터 예방까지
📅 2025. 10. 23.
🎯 Memory leak in JavaScript applications
ReferenceError: variable is not defined 완벽 해결 가이드 – JavaScript 에러 해결
📅 2025. 10. 23.
🎯 ReferenceError: variable is not defined
💡 위 글들을 통해 더 깊이 있는 정보를 얻어보세요!
📢 이 글이 도움되셨나요? 공유해주세요!
여러분의 공유 한 번이 더 많은 사람들에게 도움이 됩니다 ✨
🔥 공유할 때마다 블로그 성장에 큰 힘이 됩니다! 감사합니다 🙏
💬 여러분의 소중한 의견을 들려주세요!
Promise rejection unhandled 관련해서 궁금한 점이 더 있으시다면 언제든 물어보세요!
⭐ 모든 댓글은 24시간 내에 답변드리며, 여러분의 의견이 다른 독자들에게 큰 도움이 됩니다!
🎯 건설적인 의견과 경험 공유를 환영합니다 ✨
🔔 블로그 구독하고 최신 글을 받아보세요!
🌟 JavaScript 에러부터 다양한 실생활 정보까지!
매일 새로운 유용한 콘텐츠를 만나보세요 ✨
📧 RSS 구독 | 🔖 북마크 추가 | 📱 모바일 앱 알림 설정
지금 구독하고 놓치는 정보 없이 업데이트 받아보세요!