Process Exception
https://nodejs.org/api/process.html를 참고해
Node.js에서 Process Exception을 올바로 사용하는 방법에 대해 정리한다.
Process 객체의 이벤트 종류
beforeExit
disconnect
exit
message
uncaughtException
uncaughtExceptionMonitor
unhandledRejection
warning
worker
- signal events
SIGTERM
SIGINT
- ...(See more)
- ...
uncaughtException
uncaughtException
의 경우, 최후의 수단으로 사용되어야 하며, 사용시에 주의해야한다. 해당 예외의 경우 application이 undefined
상태라는 의미로, 예기치 못한 에러를 발생시킬 수 있다.
또한 이 event handler 내부에서 발생하는 에러는 잡히지 않기 때문에 프로세스는 non-zero exit code를 발생시켜, 예외 발생이 재귀적으로 반복되는 것을 막는다.
올바른 사용 방법은 할당된 리소스의 동기적인 cleanup 작업을 수행하는 것이다.
코드를 보면 다음과 같다.
import process from "node:process";
process.on("uncaughtException", (err, origin) => {
fs.writeSync(
process.stderr.fd,
`Caught exception: ${err}\n` + `Exception origin: ${origin}`
);
});
setTimeout(() => {
console.log("This will still run.");
}, 500);
// Intentionally cause an exception, but don't catch it.
nonexistentFunc();
console.log("This will not run.");
위의 코드를 보면, Node.js의 default handler의 동작(stderr
출력 및 exit with code 1
)을 overriding 한 것을 확인할 수 있다.
nonexistentFunc()
에서 예외가 발생 하고, uncaughtException
이벤트가 트리거 되는데, default handler의 동작을 overriding 했으므로 console.log('This will not run.');
가 실행되지 않는 것이 다.
즉, uncaughtException
handler를 직접 등록함으로써, 프로세스를 계속 실행할 지 종료할 지 선택할 수 있다는 것이다. 그래서 사용에 주의해야 한다.
unhandledRejection
unhandledRejection
이벤트는 Promise reject 됐지만, 그 rejection을 처리하는 handler가 없을 때 발생한다. 만일 handler가 추가 되면 rejectionHandled
이벤트가 발생한다.
signal events
SIGTERM
의 경우, non-Windows 환경에만 가능한데, SIGINT
를 사용하면 모든 플랫폼에서 사용가능하다.
만일 이 두 가지 중 하나가 등록 돼 있다면, default handler(128 + signal number
라는 exit code와 함께 터미널 모드를 리셋한다)는 제거된다.
SIGINT
, SIGTERM
, SIGKILL
의 경우, 타겟 프로세스를 강제로 종료시키기 때문에, 서브 프로세스는 프로세스가 시그널과 함께 종료 됐다고 알린다.