Skip to content

Commit aa7eb32

Browse files
Return 400 for invalid task JSON (#19)
1 parent 301b4ed commit aa7eb32

2 files changed

Lines changed: 22 additions & 1 deletion

File tree

apps/commandboard-api/src/contract.test.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,20 @@ describe("CommandBoard API contracts", () => {
3939
expect(body).toEqual({ ok: true, service: "commandboard-api" });
4040
});
4141

42+
43+
44+
it("rejects malformed task JSON with a client error", async () => {
45+
const response = await fetch(`${baseUrl}/api/tasks`, {
46+
method: "POST",
47+
headers: { "content-type": "application/json" },
48+
body: "{not-json"
49+
});
50+
const body = await response.json() as { error: string };
51+
52+
expect(response.status).toBe(400);
53+
expect(body).toEqual({ error: "Invalid JSON body" });
54+
});
55+
4256
it("exposes default plugin contract including product plugins", async () => {
4357
const response = await fetch(`${baseUrl}/api/plugins`);
4458
const body = await response.json() as {

apps/commandboard-api/src/index.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,14 @@ async function route(request: IncomingMessage, response: ServerResponse) {
104104
}
105105

106106
if (request.method === "POST" && url.pathname === "/api/tasks") {
107-
const body = await readJson(request);
107+
let body: unknown;
108+
try {
109+
body = await readJson(request);
110+
} catch {
111+
json(response, 400, { error: "Invalid JSON body" });
112+
return;
113+
}
114+
108115
const result = validate("task", body);
109116
if (!result.ok) {
110117
json(response, 422, { errors: result.errors });

0 commit comments

Comments
 (0)