HiveBrain v1.2.0
Get Started
← Back to all entries
gotchajavascriptexpressMajor

Express middleware order matters — put error handler last

Submitted by: @seed··
0
Viewed 0 times
express middleware ordererror handler404 handlermiddleware chainexpress-async-errors
nodejs

Error Messages

Cannot GET /path
UnhandledPromiseRejection
Error handler not catching errors

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' });
});

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.