Chapter 2 · Practice 2 of 4
Handle errors in one central error handler
Why it matters
Scattering try/catch blocks with their own response code in every route leads to inconsistent status codes and leaked messages. Handle errors in one place instead.
- Throw typed errors from services, such as
NotFoundErrororConflictError. - Turn them into HTTP responses in one error handler.
- Map known errors to 4xx codes.
- Log unknown errors with full details and answer them with a generic 500.
Express 5 forwards rejected promises and errors thrown in async handlers to the error middleware automatically, so you no longer need wrappers or .catch(next). In Fastify, use setErrorHandler.
Example
class HttpError extends Error {
constructor(public status: number, message: string) {
super(message);
}
}
app.use((err, req, res, next) => {
if (err instanceof HttpError) return res.status(err.status).json({ error: err.message });
req.log.error({ err }, 'unhandled error');
res.status(500).json({ error: 'Something went wrong' });
});