What is an unhandled promise rejection, and how do you catch it?
An unhandled rejection is a promise that rejects and never gets a rejection handler. It happens by accident: a function returns a promise, the caller forgets to return it or to await it, and the failure has nowhere to go.
In a browser the runtime reports it. The console shows an unhandled rejection error and the global error event fires, which is how error monitoring services pick it up. The page keeps running, so the failure is invisible unless someone is watching the console.
In Node the behaviour is stricter. Since version fifteen, an unhandled rejection terminates the process with a non-zero exit code, on the grounds that a silent failure in a server is worse than a crash. You can register a handler for the unhandledRejection event, and you can change the default behaviour entirely, but the better fix is always to find the call that is missing its handler.
How to prevent them in the first place. Return every promise from the function that starts it, so the caller can decide what to do with it. Await it inside a try block when you need to recover from the failure. Attach a catch handler to anything you fire and forget. And when you genuinely do not care about a failure, say so on purpose with a catch that logs, rather than by leaving the promise bare.
One trap to avoid. Adding a catch handler that only logs still leaves the outer promise fulfilled, so a caller who was relying on the rejection never learns about the failure. If the failure matters, throw again after logging.