Node.js › Async Patterns
What is the difference between an unhandled promise rejection and an uncaught exception in Node.js, and how does Node handle each by default?
AdvancedAnswer
An uncaught exception is a synchronous throw that propagates all the way up without being caught, which crashes the Node.js process immediately by default (via the 'uncaughtException' event, which should only ever be used for cleanup/logging before exiting, never to keep the process alive). An unhandled promise rejection happens when a rejected promise has no .catch() handler attached anywhere in its chain -- historically this only printed a warning, but as of modern Node.js versions the default behavior is to also terminate the process (configurable via the --unhandled-rejections flag), treating it with the same seriousness as an uncaught exception.
process.on('uncaughtException', (err) => {
console.error('Uncaught exception, shutting down:', err);
process.exit(1); // cleanup only, never suppress and continue
});
process.on('unhandledRejection', (reason) => {
console.error('Unhandled rejection:', reason);
process.exit(1);
});Real-world example A production incident where a service silently stopped processing jobs (rather than crashing loudly) is traced to an unhandled promise rejection inside a fire-and-forget async call; adding a process-level unhandledRejection handler that logs and exits ensures future occurrences fail loudly and get restarted by the process manager instead of hanging silently.