Order of Middleware & Error Middleware
In Express, the order in which you define middleware matters a lot. Think of it like an assembly line – each station processes the item in a specific sequence. If you put a station in the wrong place, things won't work correctly. Similarly, error-handling middleware has a special place and purpose.
Why Order Matters
Middleware functions are executed in the order they are defined. If you define middleware after a route that sends a response, it will never run because the request-response cycle has already ended.
const express = require('express');
const app = express();
// This middleware runs for every request
app.use((req, res, next) => {
console.log('Middleware 1 - always runs');
next();
});
app.get('/', (req, res) => {
res.send('Home Page');
});
// This middleware is defined AFTER the route
// It will NEVER run for '/' because the response was already sent
app.use((req, res, next) => {
console.log('This will never run for the home page');
next();
});Example: Correct Order
// 1. Built-in middleware first
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// 2. Custom middleware
app.use(logger);
// 3. Routes
app.get('/', (req, res) => {
res.send('Home');
});
// 4. Error-handling middleware (always last)
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send('Something broke!');
});Middleware Execution Flow
When a request arrives:
- It passes through each middleware in order until one sends a response or passes to the route.
- If a middleware calls
next(), control goes to the next middleware. - If a middleware sends a response, the cycle ends.
- After the route sends a response, no further middleware runs.
Error-Handling Middleware
Error-handling middleware is special – it takes FOUR parameters instead of three: (err, req, res, next). Express recognizes it as error-handling middleware by the four parameters.
// Error-handling middleware
app.use((err, req, res, next) => {
console.error('Error caught:', err.message);
res.status(500).json({
error: 'Something went wrong',
message: err.message
});
});How Errors Are Triggered
When you pass an error to
next(), Express skips all regular middleware and goes directly to error-handling middleware.app.get('/user/:id', (req, res, next) => {
const userId = req.params.id;
if (!isValidId(userId)) {
// Pass error to error-handling middleware
const err = new Error('Invalid user ID');
err.status = 400;
next(err);
} else {
// No error, proceed normally
res.send('User found');
}
});
// This catches errors from the route above
app.use((err, req, res, next) => {
const status = err.status || 500;
res.status(status).json({
error: err.message
});
});Practical Example with Order
const express = require('express');
const app = express();
// 1. Logging middleware - runs first
app.use((req, res, next) => {
console.log(`${req.method} ${req.url}`);
next();
});
// 2. JSON parsing
app.use(express.json());
// 3. Authentication middleware (for protected routes)
const checkAuth = (req, res, next) => {
if (req.headers.token) {
next();
} else {
const err = new Error('Authentication required');
err.status = 401;
next(err);
}
};
// 4. Protected routes (use checkAuth)
app.get('/dashboard', checkAuth, (req, res) => {
res.send('Dashboard');
});
// 5. Public routes (no auth needed)
app.get('/', (req, res) => {
res.send('Home');
});
// 6. 404 handler - if no route matched
app.use((req, res) => {
res.status(404).send('Page not found');
});
// 7. Error-handling middleware - always last
app.use((err, req, res, next) => {
const status = err.status || 500;
res.status(status).json({
error: err.message
});
});Two Minute Drill
- Middleware order determines execution sequence – define them in the order you want them to run.
- Place error-handling middleware LAST.
- Error-handling middleware has four parameters (err, req, res, next).
- Pass errors to
next(err)to trigger error-handling middleware. - Always put 404 handlers after all routes and before error handlers.
- Middleware defined after routes won't execute for those routes.
Need more clarification?
Drop us an email at career@quipoinfotech.com
