Migrate from Express 4 to Express 5
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 19m30s

- Upgraded express from ^4.22.1 to ^5.2.1
- Added comprehensive Express 5 migration tests with TDD approach
- All 667 tests passing (663 existing + 4 new migration tests)
- No breaking changes detected in the codebase
- Express 5's native async error handling now active
- TypeScript compilation successful with @types/express ^5.0.6

Express 5 features now available:
- Automatic async error catching in route handlers
- Improved performance and stricter path matching
- Default export import style already in use
This commit is contained in:
DocFast Bot 2026-03-11 17:08:07 +01:00
parent a55c306514
commit 603cbd7061
3 changed files with 447 additions and 185 deletions

View file

@ -0,0 +1,89 @@
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
import request from "supertest";
import express, { Request, Response, NextFunction } from "express";
import { app } from "../index.js";
describe("Express 5 Migration Tests", () => {
describe("Version Check", () => {
it("should be running Express 5.x", () => {
// This test will fail on Express 4 and pass on Express 5
const expressVersion = require('express/package.json').version;
expect(expressVersion).toMatch(/^5\./);
});
});
describe("Async Error Handling", () => {
let testApp: express.Application;
beforeEach(() => {
testApp = express();
testApp.use(express.json());
});
it("should automatically catch async errors without explicit error handling (Express 5 feature)", async () => {
// Express 5 automatically catches rejected promises in route handlers
// This test verifies that behavior
let errorHandlerCalled = false;
testApp.get("/test-async-error", async (req: Request, res: Response) => {
// Deliberately cause an async error without try/catch
await new Promise((resolve, reject) => {
setTimeout(() => reject(new Error("Async test error")), 1);
});
res.json({ success: true });
});
// Add error handler
testApp.use((err: any, req: Request, res: Response, next: NextFunction) => {
errorHandlerCalled = true;
res.status(500).json({ error: "Caught async error" });
});
const response = await request(testApp)
.get("/test-async-error")
.expect(500);
expect(response.body).toEqual({ error: "Caught async error" });
expect(errorHandlerCalled).toBe(true);
});
it("should handle async errors in middleware without explicit error handling", async () => {
let errorHandlerCalled = false;
// Async middleware that throws
testApp.use(async (req: Request, res: Response, next: NextFunction) => {
await new Promise((resolve, reject) => {
setTimeout(() => reject(new Error("Middleware async error")), 1);
});
next();
});
testApp.get("/test-middleware-error", (req: Request, res: Response) => {
res.json({ success: true });
});
// Error handler
testApp.use((err: any, req: Request, res: Response, next: NextFunction) => {
errorHandlerCalled = true;
res.status(500).json({ error: "Middleware error caught" });
});
const response = await request(testApp)
.get("/test-middleware-error")
.expect(500);
expect(response.body).toEqual({ error: "Middleware error caught" });
expect(errorHandlerCalled).toBe(true);
});
});
describe("Express Import Style", () => {
it("should support default import syntax (Express 5)", () => {
// Express 5 uses default export, Express 4 uses named export
// This test verifies we can import express as default export
const express = require('express');
expect(typeof express).toBe('function');
expect(typeof express.default).toBe('undefined'); // Should not need .default
});
});
});