Skip to main content

Process Exception

https://nodejs.org/api/process.html를 참고해

Node.js에서 Process Exception을 올바로 사용하는 방법에 대해 정리한다.


Process 객체의 이벤트 종류

  • beforeExit
  • disconnect
  • exit
  • message
  • uncaughtException
  • uncaughtExceptionMonitor
  • unhandledRejection
  • warning
  • worker
  • signal events
  • ...

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의 경우, 타겟 프로세스를 강제로 종료시키기 때문에, 서브 프로세스프로세스가 시그널과 함께 종료 됐다고 알린다.

Related Links