express icon indicating copy to clipboard operation
express copied to clipboard

[Docs] Add comprehensive middleware execution order and error handling examples

Open harsha08-2k6 opened this issue 1 month ago • 1 comments

Description

Issue Description

The current Express.js documentation covers middleware basics, but lacks comprehensive examples demonstrating:

  1. Middleware execution order with multiple middleware functions
  2. Error-handling middleware best practices and common patterns
  3. Async/await middleware with proper error propagation
  4. Router-level vs application-level middleware interactions
  5. Built-in middleware execution timing and order

Current State

The existing docs at https://expressjs.com/en/guide/using-middleware.html provide basic examples, but developers (especially beginners) often struggle with:

  • Understanding when next() should be called
  • How error-handling middleware differs from regular middleware
  • Execution order when combining app.use(), router.use(), and route-specific middleware
  • Common mistakes that lead to hanging requests or uncaught errors

Proposed Improvement

Add a dedicated section or expand the existing middleware guide with:

1. Visual Execution Flow Diagram

Show the order of execution with a clear diagram or flowchart

2. Complete Working Examples

// Example: Middleware execution order
const express = require('express');
const app = express();

// Application-level middleware
app.use((req, res, next) => {
  console.log('1. App-level middleware');
  next();
});

// Router with its own middleware
const router = express.Router();
router.use((req, res, next) => {
  console.log('2. Router-level middleware');
  next();
});

router.get('/api/users', 
  (req, res, next) => {
    console.log('3. Route-specific middleware');
    next();
  },
  (req, res) => {
    console.log('4. Final route handler');
    res.json({ users: [] });
  }
);

app.use('/api', router);

// Error-handling middleware (must be last)
app.use((err, req, res, next) => {
  console.error('5. Error handler:', err);
  res.status(500).json({ error: err.message });
});

3. Common Patterns Section

  • Authentication middleware
  • Request validation
  • Async error handling wrapper
  • Response time logging

4. Troubleshooting Guide

  • "Request hangs" → forgot to call next() or send response
  • "Error not caught" → error handler not defined or placed incorrectly
  • "Middleware skipped" → route matched before middleware executed

Benefits

  • Reduces support questions and Stack Overflow posts about middleware
  • Helps developers avoid common pitfalls
  • Provides copy-paste ready examples for common use cases
  • Improves onboarding for new Express users

Related

This complements issue #6917 about async/await error handling best practices.

Expectations

The updated documentation should include:

  1. A dedicated page or expanded section on middleware execution order
  2. Interactive examples showing console output to visualize execution flow
  3. Side-by-side comparison of correct vs incorrect patterns
  4. Clear warnings about common mistakes (e.g., placing error handlers before routes)
  5. Best practices for structuring middleware in larger applications

Developers should be able to:

  • Understand middleware execution order without trial and error
  • Copy working examples for authentication, logging, and error handling
  • Debug middleware-related issues using the troubleshooting guide
  • Confidently build applications with complex middleware chains

harsha08-2k6 avatar Nov 26 '25 05:11 harsha08-2k6

The documentation is maintained in expressjs/expressjs.com, so this issue should be moved there, but let me answer some of your problems:

Execution order and next()

  1. Middleware execution order with multiple middleware functions
  • Understanding when next() should be called

To me the examples in Using Express middleware show that the middleware is executed in the same order that it is declared. All types of middleware from your example are documented. There is also information when next() should be called and how next('route') and next('router') can skip some middleware.

  1. Router-level vs application-level middleware interactions
  • Execution order when combining app.use(), router.use(), and route-specific middleware

This could maybe be somehow improved. I don't think it is explicitly written that the order is "app middleware until router" -> "router middleware until route" -> "route middleware". It shouldn't be unexpected for most people, but stating it in the docs could be helpful for someone.

Error handling

  1. Error-handling middleware best practices and common patterns
  • How error-handling middleware differs from regular middleware

There is a separate guide Express error handling which describes this, including among other things the differences in signature (also in Using middleware guide) and that it should be defined last.

Promises, async/await and error handling

  1. Async/await middleware with proper error propagation

This is also described in the Express error handling guide.

And by the way there is no need for async error handling wrappers - rejected Promises are caught and call next(value) (see the guide).

Built-in middleware

  1. Built-in middleware execution timing and order

What do you mean by this? It's normal middleware that is executed in the same way as everything else. It doesn't get magically executed at random time. You should think of it as of third-party middleware that is a re-exported dependency of Express.

Common mistakes

  • Common mistakes that lead to hanging requests or uncaught errors

There is no separate section for this, but there is an information that next() should be called or the request will be left hanging and that error handling middleware should be defined last (possible cause of uncaught errors).

Common patterns

Some of this is described in the Writing middleware for use in Express guide, FAQ and maybe examples:

krzysdz avatar Dec 01 '25 17:12 krzysdz