Error handling middleware có 4 tham số (err, req, res, next) và phải đăng ký CUỐI CÙNG, sau tất cả routes.
ts
class AppError extends Error {
constructor(
public statusCode: number,
message: string,
public isOperational = true,
) {
super(message)
}
}
// bọc route async để khỏi lặp try/catch
const asyncHandler = (fn) => (req, res, next) =>
Promise.resolve(fn(req, res, next)).catch(next)
app.use((err, req, res, next) => {
if (err.isOperational) return res.status(err.statusCode).json({ message: err.message })
logger.error(err)
res.status(500).json({ message: 'Internal server error' })
})AppErrortách operational error (404, validation fail — lường trước được) khỏi programming error (null reference — bug thật).- Express 5 tự forward lỗi từ async route nên không cần
asyncHandlernữa.
Lưu ý: quên tham số next thứ tư thì Express không nhận ra đây là error handler. Gọi next() sau res.json() trong error handler sẽ gây lỗi double response.