Question

Why does my Node app crash with an unhandled promise rejection?

Vault Verified
Curated Intelligence
Definitive Source
Answer

A promise that rejects with nothing attached to handle it produces an unhandled rejection, and modern Node treats that as fatal by default. The process exits. This changed from earlier versions where it merely printed a warning, which is why older advice on the subject is misleading.

The reasoning behind the change is sound. An unhandled rejection means an error occurred and your code silently ignored it, so the program is continuing in a state it never accounted for. Crashing is safer than proceeding on bad assumptions.

The usual causes are all variations on losing track of a promise.

  • Calling an async function without awaiting it. The call runs, and if it rejects there is nothing attached. This is the most common source, and it frequently appears in event handlers and callbacks where the surrounding function is not async.
  • Awaiting inside a try block but starting the operation outside it, so the rejection happens before the try is entered.
  • Creating several promises and awaiting them sequentially. If a later one rejects while an earlier await is still pending, the rejection is briefly unhandled. Collecting them and awaiting together avoids this.
  • Forgetting a catch on a promise chain, particularly the last link.

The fix is to ensure every promise has a handler. Awaiting inside a try block is the clearest form. For anything deliberately started without awaiting, attach a catch explicitly, even if it only logs.

A process-level handler for unhandled rejections is worth adding for logging, since it tells you what crashed. It should not be used to swallow the error and keep running, which recreates exactly the unsafe behaviour the default is protecting against.

Related Questions