chore: update marked 17.0.5, add global error handler tests (TDD)

This commit is contained in:
OpenClaw Subagent 2026-03-20 17:07:56 +01:00
parent eea9489efc
commit ab89085a0b
3 changed files with 130 additions and 5 deletions

8
package-lock.json generated
View file

@ -12,7 +12,7 @@
"express": "^5.1.0",
"express-rate-limit": "^8.3.1",
"helmet": "^8.1.0",
"marked": "^17.0.4",
"marked": "^17.0.5",
"nanoid": "^5.1.6",
"nodemailer": "^8.0.2",
"pg": "^8.20.0",
@ -3464,9 +3464,9 @@
}
},
"node_modules/marked": {
"version": "17.0.4",
"resolved": "https://registry.npmjs.org/marked/-/marked-17.0.4.tgz",
"integrity": "sha512-NOmVMM+KAokHMvjWmC5N/ZOvgmSWuqJB8FoYI019j4ogb/PeRMKoKIjReZ2w3376kkA8dSJIP8uD993Kxc0iRQ==",
"version": "17.0.5",
"resolved": "https://registry.npmjs.org/marked/-/marked-17.0.5.tgz",
"integrity": "sha512-6hLvc0/JEbRjRgzI6wnT2P1XuM1/RrrDEX0kPt0N7jGm1133g6X7DlxFasUIx+72aKAr904GTxhSLDrd5DIlZg==",
"license": "MIT",
"bin": {
"marked": "bin/marked.js"

View file

@ -16,7 +16,7 @@
"express": "^5.1.0",
"express-rate-limit": "^8.3.1",
"helmet": "^8.1.0",
"marked": "^17.0.4",
"marked": "^17.0.5",
"nanoid": "^5.1.6",
"nodemailer": "^8.0.2",
"pg": "^8.20.0",

View file

@ -0,0 +1,125 @@
import { describe, it, expect, vi, beforeEach } from "vitest";
import express from "express";
import request from "supertest";
let app: express.Express;
beforeEach(async () => {
vi.clearAllMocks();
vi.resetModules();
// Create a minimal test app that mimics the structure of the main app
app = express();
// Add request ID middleware (used by error handler)
app.use((req, _res, next) => {
req.requestId = "test-request-id";
next();
});
// Add JSON parsing middleware
app.use(express.json({ limit: "500kb" }));
// Add test routes that can throw errors
app.post("/v1/convert/html", (_req, _res, next) => {
const err = new Error("Test API error");
next(err);
});
app.get("/v1/test-error", (_req, _res, next) => {
const err = new Error("Test V1 error");
next(err);
});
app.get("/health/test-error", (_req, _res, next) => {
const err = new Error("Test health error");
next(err);
});
app.get("/non-api/test-error", (_req, _res, next) => {
const err = new Error("Test non-API error");
next(err);
});
// Import and add the global error handler from index.ts
// We need to copy the exact error handler logic
app.use((err: unknown, req: express.Request, res: express.Response, _next: express.NextFunction) => {
const reqId = req.requestId || "unknown";
// Check if this is a JSON parse error from express.json()
if (err instanceof SyntaxError && 'status' in err && (err as Record<string, unknown>).status === 400 && 'body' in err) {
if (!res.headersSent) {
res.status(400).json({ error: "Invalid JSON in request body" });
}
return;
}
if (!res.headersSent) {
const isApi = req.path.startsWith("/v1/") || req.path.startsWith("/health");
if (isApi) {
res.status(500).json({ error: "Internal server error" });
} else {
res.status(500).send("Internal server error");
}
}
});
});
describe("global error handler", () => {
it("returns 400 JSON response for invalid JSON body", async () => {
const response = await request(app)
.post("/v1/convert/html")
.set("Content-Type", "application/json")
.send("{ invalid json content")
.expect(400);
expect(response.body).toEqual({
error: "Invalid JSON in request body"
});
expect(response.headers["content-type"]).toMatch(/application\/json/);
});
it("returns 500 JSON response for errors on /v1/* API paths", async () => {
const response = await request(app)
.get("/v1/test-error")
.expect(500);
expect(response.body).toEqual({
error: "Internal server error"
});
expect(response.headers["content-type"]).toMatch(/application\/json/);
});
it("returns 500 JSON response for errors on /health API paths", async () => {
const response = await request(app)
.get("/health/test-error")
.expect(500);
expect(response.body).toEqual({
error: "Internal server error"
});
expect(response.headers["content-type"]).toMatch(/application\/json/);
});
it("returns 500 plain text response for errors on non-API paths", async () => {
const response = await request(app)
.get("/non-api/test-error")
.expect(500);
expect(response.text).toBe("Internal server error");
expect(response.headers["content-type"]).toMatch(/text\/html/);
});
it("handles POST requests with valid JSON but route throws error (API path)", async () => {
const response = await request(app)
.post("/v1/convert/html")
.set("Content-Type", "application/json")
.send({ html: "<h1>Test</h1>" })
.expect(500);
expect(response.body).toEqual({
error: "Internal server error"
});
expect(response.headers["content-type"]).toMatch(/application\/json/);
});
});