Node.js: unhandled promise rejection crashes my server

poze a month ago374 gadeen

5

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?

🤖 Dyagnostik IA

Se IA ki fè l. Se pa yon repons — kominote a anba a konfime oswa korije l. Toujou verifye anvan ou fye l.

  • Thanks, this helped. Did you also try clearing the cache?

    marielouis 5 days ago

2 Repons

2

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.

Konekte pou di lòt moun si li te mache.

answered a month ago
0

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:

  1. 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);
}));
  1. 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 existing async route handlers work as-is with your normal Express error-handling middleware.

  2. 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.

  3. 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.

Konekte pou di lòt moun si li te mache.

answered a day ago

Sign in and verify your email to post an answer.