Skip to content

Error Middleware — Global Error Handlers in Express and FastAPI

DodaTech Updated 2026-06-28 1 min read

In this tutorial, you will learn about Error Middleware. We cover key concepts, practical examples, and best practices to help you master this topic.

Error middleware centralizes error handling in one place, converting thrown errors into consistent HTTP responses with proper status codes, error codes, and request tracking.

Express.js"Express" >}}.js Error Middleware

class ApiError extends Error {
  constructor(statusCode, error, message, details = null) {
    super(message);
    this.statusCode = statusCode;
    this.error = error;
    this.details = details;
    this.requestId = generateRequestId();
    this.timestamp = new Date().toISOString();
  }
}

const Errors = {
  notFound: (resource) => new ApiError(404, "not_found", `${resource} not found`),
  validationError: (details) => new ApiError(422, "validation_error", "Validation failed", details),
  unauthorized: () => new ApiError(401, "unauthorized", "Authentication required"),
  forbidden: () => new ApiError(403, "forbidden", "Insufficient permissions"),
  conflict: (msg) => new ApiError(409, "conflict", msg),
  tooManyRequests: () => new ApiError(429, "rate_limited", "Rate limit exceeded"),
  internal: () => new ApiError(500, "internal_error", "An unexpected error occurred")
};

app.use((err, req, res, next) => {
  const statusCode = err.statusCode || 500;
  const response = {
    status: statusCode,
    error: err.error || "internal_error",
    message: statusCode === 500 ? "An unexpected error occurred" : err.message,
    requestId: err.requestId || generateRequestId(),
    timestamp: err.timestamp || new Date().toISOString()
  };

  if (err.details) response.details = err.details;
  res.status(statusCode).json(response);
});

FastAPI Error Handler

from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse

class ApiError(Exception):
    def __init__(self, status_code: int, error: str, message: str, details: list = None):
        self.status_code = status_code
        self.error = error
        self.message = message
        self.details = details

@app.exception_handler(ApiError)
async def api_error_handler(request: Request, exc: ApiError):
    return JSONResponse(
        status_code=exc.status_code,
        content={
            "status": exc.status_code,
            "error": exc.error,
            "message": exc.message,
            "details": exc.details,
            "requestId": str(uuid.uuid4()),
            "timestamp": datetime.utcnow().isoformat()
        }
    )

Common Mistakes

  1. No error middleware — Handling errors inline in every controller.
  2. Not catching all exceptions — Unhandled errors return HTML or 500.
  3. Mixing error handling logic — Error middleware should only format responses.

Practice Questions

  1. What is the benefit of centralized error middleware?
  2. How do custom error classes simplify error handling?
  3. What should error middleware do with unhandled exceptions?

Challenge

Implement complete error middleware for an Express API. Create error classes for all common status codes, a global handler, and test that all errors return consistent format.

What's Next

In the next lesson, you will learn error logging strategies.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro