gotchajavascriptexpressMajor
Express middleware order matters — put error handler last
Viewed 0 times
express middleware ordererror handler404 handlermiddleware chainexpress-async-errors
nodejs
Error Messages
Problem
Express error handling middleware doesn't catch errors if it's defined before routes. Also, 404 handlers must come after all routes. Middleware executes in the order it's defined.
Solution
Order your middleware correctly:
const express = require('express');
const app = express();
// 1. Built-in middleware FIRST
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cors());
// 2. Custom middleware (logging, auth)
app.use(requestLogger);
app.use('/api', authMiddleware);
// 3. Routes
app.use('/api/users', userRoutes);
app.use('/api/posts', postRoutes);
// 4. 404 handler (after all routes)
app.use((req, res) => {
res.status(404).json({ error: 'Not found' });
});
// 5. Error handler LAST (must have 4 params!)
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({ error: 'Internal server error' });
});
const express = require('express');
const app = express();
// 1. Built-in middleware FIRST
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cors());
// 2. Custom middleware (logging, auth)
app.use(requestLogger);
app.use('/api', authMiddleware);
// 3. Routes
app.use('/api/users', userRoutes);
app.use('/api/posts', postRoutes);
// 4. 404 handler (after all routes)
app.use((req, res) => {
res.status(404).json({ error: 'Not found' });
});
// 5. Error handler LAST (must have 4 params!)
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({ error: 'Internal server error' });
});
Why
Express processes middleware in order. If the error handler is defined before routes, it's never reached. Express identifies error handlers by their 4-parameter signature (err, req, res, next) — if you omit any parameter, it's treated as regular middleware.
Gotchas
- Error handler MUST have exactly 4 parameters — even if you don't use next
- Async errors need explicit next(err) or express-async-errors package
- app.use without a path matches ALL routes
- Static file middleware (express.static) should come before API routes
Code Snippets
Express error handling pattern
// Error handler: MUST have 4 params
app.use((err, req, res, next) => {
res.status(err.status || 500).json({ error: err.message });
});
// Async error handling
const asyncHandler = (fn) => (req, res, next) =>
Promise.resolve(fn(req, res, next)).catch(next);Context
When setting up Express.js application middleware
Revisions (0)
No revisions yet.