

0 / 2 embers
0 / 3000 xp
click for more info
Complete a lesson to start your streak
click for more info
Still calibrating
click for more info
Not enough gems
Cost: 6 gems
1: Data Leaks
incomplete
2: Sanitizing Error Messages
incomplete
3: Global Error Handling
incomplete
4: Sanitizing Logs
incomplete
Back
ctrl+,
Next
ctrl+.
This lesson's interactive features are locked, please to keep using them
A safe error page is useless if one forgotten route sends an exception straight to the client. In Express, error-handling middleware gives you one final boundary between private failures and public responses.
You create error-handling middleware by giving it four parameters: (err, req, res, next). Register it after your routes so Express can call it when a route throws an exception or passes an error to next(err):
import type { ErrorRequestHandler } from "express";
const errorHandler: ErrorRequestHandler = (err, req, res, next) => {
if (res.headersSent) {
next(err);
return;
}
const details = err instanceof Error ? err : new Error(String(err));
logger.error("Unhandled error", {
message: details.message,
stack: details.stack,
path: req.path,
});
res.status(500).json({ error: "Something went wrong" });
};
app.use(errorHandler);
Some errors are expected or route-specific and should be handled in the route. A missing concert ticket should get a deliberate 404, and invalid checkout input should get a client-safe 400. An unexpected database or filesystem failure belongs at the global boundary, where it can be logged and returned as a safe 500.
Handle failures locally when the route expects them. Forward unexpected failures so one global handler can log the details and return a safe 500.