For Express apps, standardize error handling as follows:
(err, req, res, next).next(err) via try/catch or an asyncHandler helper.Example (safe ordering + async propagation):
const express = require('express');
const app = express();
// Routes
app.get('/', (req, res) => {
throw new Error('Something went wrong');
});
// 404 handler (after routes, before error handler)
app.use((req, res) => {
res.status(404).send('Sorry, that route does not exist.');
});
// Async error helper (optional)
function asyncHandler(fn) {
return (req, res, next) => Promise.resolve(fn(req, res, next)).catch(next);
}
app.get('/user', asyncHandler(async (req, res) => {
const user = await getUserFromDatabase();
res.send(user);
}));
// Error-handling middleware (LAST)
app.use((err, req, res, next) => {
console.error(err); // log details internally
res.status(500).send('Internal Server Error'); // user-friendly response
});
Apply this checklist consistently when adding new routes or refactoring middleware order to prevent unhandled promise rejections, ensure consistent HTTP responses, and avoid leaking sensitive error details.