We need to cover two important types of middleware that help handle errors and missing routes in your Express application.

404 Handler Middleware

A 404 handler catches requests to routes that don’t exist. It should be placed after all your regular routes but before your error handling middleware.

// 404 handler - catches all unmatched routes
app.use((req, res) => {
  res.status(404).json({
    error: "Route not found",
    message: `Cannot ${req.method} ${req.originalUrl}`,
  });
});

How it works:

  • app.use(...) without a path matches any route that hasn’t been handled by previous middleware or routes
  • It sends a 404 status with a helpful error message
  • req.originalUrl shows the exact URL that was requested

Error Handling Middleware

Error handling middleware catches any unhandled errors that occur in your application. It has a special signature with 4 parameters and must come last in your middleware stack.

// Error handling middleware - must have 4 parameters
app.use((err: Error, req, res, next) => {
  console.error("Error occurred:", err.message);

  res.status(500).json({
    error: "Internal server error",
    message:
      process.env.NODE_ENV === "development"
        ? err.message
        : "Something went wrong",
  });
});

Note: We type Error here to highlight that this middleware has a special 4-parameter signature that Express recognises for error handling.

Important characteristics:

  • Must have 4 parameters (err, req, res, next) - Express recognises error middleware by this signature
  • Goes last in your middleware stack
  • Catches unhandled errors from any previous middleware or routes
  • Should not expose error details in production for security reasons

Testing Your Error Handling Middleware

To test that your error handling middleware works, you can create a test route that deliberately throws an error:

// Test route to trigger error handling middleware
app.get("/test-error", (req, res) => {
  throw new Error("This is a test error!");
});

When you visit http://localhost:3000/test-error, this route will:

  1. Throw an error
  2. The error gets caught by your error handling middleware
  3. Your error handler sends a 500 response with the error details

Important: Remember to remove test routes like this before deploying to production.



Repo link

Tags: