Handle invalid JSON request bodies (#7)

This commit is contained in:
phucnguyen1707 2026-06-12 11:00:38 +07:00 committed by GitHub
parent 850cf5ea44
commit ad9f3a2a29
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 31 additions and 1 deletions

View file

@ -181,4 +181,16 @@ describe("CommandBoard API contracts", () => {
expect(response.status).toBe(422); expect(response.status).toBe(422);
expect(Array.isArray(body.errors)).toBe(true); expect(Array.isArray(body.errors)).toBe(true);
}); });
it("rejects malformed JSON request bodies as client errors", async () => {
const response = await fetch(`${baseUrl}/api/tasks`, {
method: "POST",
headers: { "content-type": "application/json" },
body: "{bad"
});
const body = await response.json() as { error: string };
expect(response.status).toBe(400);
expect(body).toEqual({ error: "Invalid JSON body" });
});
}); });

View file

@ -55,11 +55,22 @@ const c0mputeWorkers = [
{ id: "worker_pool_1", region: "us-west", status: "preview", capacity: "wip" } { id: "worker_pool_1", region: "us-west", status: "preview", capacity: "wip" }
]; ];
class InvalidJsonBodyError extends Error {
constructor() {
super("Invalid JSON body");
this.name = "InvalidJsonBodyError";
}
}
export function createCommandBoardServer() { export function createCommandBoardServer() {
return createServer(async (request, response) => { return createServer(async (request, response) => {
try { try {
await route(request, response); await route(request, response);
} catch (error) { } catch (error) {
if (error instanceof InvalidJsonBodyError) {
json(response, 400, { error: error.message });
return;
}
json(response, 500, { error: error instanceof Error ? error.message : String(error) }); json(response, 500, { error: error instanceof Error ? error.message : String(error) });
} }
}); });
@ -287,7 +298,14 @@ async function readJson(request: IncomingMessage) {
chunks.push(Buffer.from(chunk)); chunks.push(Buffer.from(chunk));
} }
return JSON.parse(Buffer.concat(chunks).toString("utf8")) as unknown; try {
return JSON.parse(Buffer.concat(chunks).toString("utf8")) as unknown;
} catch (error) {
if (error instanceof SyntaxError) {
throw new InvalidJsonBodyError();
}
throw error;
}
} }
function isRecord(value: unknown): value is Record<string, unknown> { function isRecord(value: unknown): value is Record<string, unknown> {