Node.js: unhandled promise rejection crashes my server
asked a month ago377 viewsen
Since Node 15+, an unhandled rejection terminates the process. How should I structure a large Express app to catch all async errors in route handlers?
🤖 AI diagnosis
AI-generated. Not an answer — the community below confirms or corrects it. Always verify before relying on it.
Thanks, this helped. Did you also try clearing the cache?
— marielouis 5 days ago
2 Answers
Wrap handlers so rejections reach your error middleware:
const wrap = fn => (req, res, next) => Promise.resolve(fn(req, res, next)).catch(next);
app.get('/x', wrap(async (req, res) => { /* ... */ }));
Or upgrade to Express 5, which does this automatically.
Sign in to tell others whether this worked.
Answer
The core recommendation from the discussion is to stop relying on global unhandledRejection handlers as your main safety net and instead catch async errors at the route level, since Node 15+ will crash the process on an unhandled rejection.
For a large Express app, the common pattern is:
- Wrap every async route handler so rejected promises are passed to
next()instead of being left unhandled:
const asyncHandler = (fn) => (req, res, next) => {
Promise.resolve(fn(req, res, next)).catch(next);
};
app.get('/route', asyncHandler(async (req, res) => {
const data = await someAsyncCall();
res.json(data);
}));
-
Centralize this so you don't have to remember to wrap each handler manually — either apply the wrapper in your route registration helper, or use a library like
express-async-errors(which monkey-patches Express to auto-catch async errors) so your existingasyncroute handlers work as-is with your normal Express error-handling middleware. -
Keep a standard Express error-handling middleware (the 4-arg
(err, req, res, next)one) at the end of your middleware stack to actually respond to these forwarded errors instead of letting them crash the app. -
It's still a good idea to keep a top-level
process.on('unhandledRejection', ...)/process.on('uncaughtException', ...)as a last-resort logger for anything that slips through (e.g., errors in non-request code like background jobs, timers, etc.), but it shouldn't be your primary strategy for route handlers.
Unfortunately, the rest of the discussion (the "clearing the cache" comment) doesn't seem related to this issue — that seems to be a mismatched or unrelated reply, so it's probably safe to disregard it here.
Not yet covered / worth digging into further: if you're on Express 5 (still in beta/rc at time of writing), async error handling for route handlers is built in natively, so you may not need express-async-errors at all — worth checking your Express version before adding the dependency.
Sign in to tell others whether this worked.
Sign in and verify your email to post an answer.