Node.js › Error Handling
Why doesn't Express automatically catch errors thrown inside an async route handler in versions prior to Express 5, and how do you work around this?
IntermediateAnswer
In Express 4 and earlier, if an async function passed as a route handler throws (or its returned promise rejects), Express's underlying error-handling doesn't automatically catch it the way it does for synchronous throws, because Express predates widespread async/await and doesn't await the handler's returned promise -- the common workaround wraps every async handler in a helper that catches rejections and forwards them to next(), or uses a library like express-async-errors that patches this behavior globally.
// Manual wrapper approach
const asyncHandler = (fn) => (req, res, next) => Promise.resolve(fn(req, res, next)).catch(next);
app.get('/users/:id', asyncHandler(async (req, res) => {
const user = await getUserOrThrow(req.params.id); // if this throws, asyncHandler catches and forwards it
res.json(user);
}));Real-world example A team on Express 4 noticed that an unhandled rejection inside an async route handler was crashing their entire server rather than being caught by their error middleware, until they wrapped every async route with a small asyncHandler utility that properly forwards rejected promises to Express's next() function.