NodeJS UnhandledPromiseRejectionWarning

Jeongkuk Seo
sjk5766
Published in
4 min readJun 6, 2021

정말 오랜만의 포스팅이네요. (반성반성..) 오늘은 핸들링 되지 않은 reject를 처리하는 방법을 다루려 합니다.

express 프레임워크로 서버를 띄우고 라우터에 아래 코드를 작성합니다.

router.get('/', function(req, res, next) {
return Promise.reject('aa')
});

module.exports = router;

서버에 접속하면 promise reject가 정상적으로 catch 되지 않기 때문에 아래 로그를 확인할 수 있습니다.

Node v15 부터 unhandledRejection은 warning이 아닌 throw로 발생하기 때문에 프로세스가 죽게 됩니다. 이 때, 개발자의 실수로 핸들링을 하지 못한 reject는 다음과 같이 unhandledRejection 이벤트를 감지하여 핸들링 할 수 있습니다.

process.on('unhandledRejection', (err, promise) => {
console.log('Unhandled Rejection detect:', err.stack || err)
})

해당 코드를 app.js에 추가하고 서버에 접속하면 아래와 같은 로그를 볼 수 있습니다.

여기서 문제는 어느 코드에서 에러가 발생했는지 확인할 수가 없습니다. stack trace 정보를 확인할 수 있도록 Erorr 객체를 리턴하도록 라우터쪽 코드를 변경하겠습니다.

router.get('/', function(req, res, next) {
return Promise.reject(new Error('aa'))
});

위 처럼 에러 객체를 리턴할 경우 정상적으로 stack trace를 확인할 수 있습니다. 따라서 코드에서는 에러 메시지 같은 문자열이 아닌 에러 객체를 반환하는것이 좋습니다.

위 방식은 개발중에 debug 를 위해 사용하는 것이 좋고 실제 서비스에는 사용하지 않는것이 좋습니다. 가령 unhandledRejection이 발생했을 때, 사후처리(로깅, 관리자 계정으로 메일전송 등등)를 하고 죽는다고 가정해보겠습니다.

이 때 Database가 죽는 등의 이유로, unhandledRejection가 여러번 호출되면 사후코드에서 문제가 발생할 수 있기 때문에 개발 중 Debug용도로만 사용하는게 좋을 것 같습니다.

레퍼런스

--

--