Building RESTful APIsLesson 3.3
Express error handling middleware — how to catch all errors
error handler middleware, 4-parameter signature, next(err), app.use placement, operational vs programmer errors, custom AppError class, centralized error handling
Centralized Error Handling in Express
Express has a built-in error-handling mechanism: any middleware with four parameters (err, req, res, next) is treated as an error handler. You pass errors to it by calling next(err).
Custom error class
class AppError extends Error {
constructor(message, statusCode, code) {
super(message);
this.statusCode = statusCode;
this.code = code;
this.isOperational = true;
}
}
module.exports = AppError;Global error handler
// middleware/errorHandler.js
function errorHandler(err, req, res, next) {
const statusCode = err.statusCode || 500;
const message = err.isOperational ? err.message : 'Internal server error';
console.error(`[ERROR] ${err.message}`, err.stack);
res.status(statusCode).json({
success: false,
error: { message, code: err.code || 'INTERNAL_ERROR' }
});
}
module.exports = errorHandler;Using it
// In routes — throw operational errors
app.get('/users/:id', (req, res, next) => {
const user = findUser(req.params.id);
if (!user) return next(new AppError('User not found', 404, 'USER_NOT_FOUND'));
res.json(user);
});
// In app.js — register AFTER all routes
app.use(errorHandler);Register the error handler after all routes. The error handler is the last safety net — uncaught programmer errors should log a stack trace but show a generic message to clients.
