Node.js · 02/19 7 min
Express request pipeline
Middleware order, next(), error handlers with four arguments, and 'headers already sent'.
express.json()
→cors()
→requireAuth
→router
→handler
→404 fallback
→errorHandler
200Every middleware calls next(); the handler responds with res.json(). Nothing after it runs.
An Express app is a list of functions tried in registration order. Each one either responds or calls next() to pass control on.
app.use(express.json()); // 1. parse body → req.body
app.use(cors()); // 2. headers
app.use("/api/orders", requireAuth, ordersRouter); // 3. auth only for this mount
app.use((req, res) => res.status(404).json({ error: "Not found" })); // 4. fallthrough
app.use((err, req, res, next) => { /* 5. error handler: FOUR args */ });
Rules that cause real bugs
- Order matters. Middleware registered after a route never runs for that route.
express.json()must come before handlers that readreq.body. - An error handler is recognised by arity.
(err, req, res, next)with four parameters. Dropnextand Express treats it as normal middleware. next(err)skips to the error handler;next()continues normally;next('route')skips the rest of the current route's handlers.- Respond once.
res.json()followed by anotherres.send()throws Cannot set headers after they are sent. Usually a missingreturnbefore an early response:
if (!user) res.status(404).json({ error: "no user" }); // ❌ falls through
if (!user) return res.status(404).json({ error: "no user" }); // ✅
- Async errors (Express 4): wrap handlers so rejections reach
next:
const wrap = (fn) => (req, res, next) => Promise.resolve(fn(req, res, next)).catch(next);
req.paramsandreq.queryare strings.req.query.limit + 1is"101".
Practise it now
Next in Node.js
Async pitfalls catalogue