diff --git a/src/utils/http-client.test.ts b/src/utils/http-client.test.ts index eba1b3e..150a7d7 100644 --- a/src/utils/http-client.test.ts +++ b/src/utils/http-client.test.ts @@ -5,3 +5,57 @@ describe("http-client", () => { expect(BASE_URL).toBe("https://magic.21st.dev"); }); }); + +describe("http-client error handling", () => { + let originalFetch: typeof fetch; + + beforeEach(() => { + originalFetch = globalThis.fetch; + }); + + afterEach(() => { + globalThis.fetch = originalFetch; + }); + + it("throws on non-2xx response with status and error message", async () => { + const { twentyFirstClient } = await import("./http-client.js"); + + globalThis.fetch = async () => + new Response(JSON.stringify({ error: "Anthropic experiencing high load" }), { + status: 500, + statusText: "Internal Server Error", + }) as Response; + + await expect( + twentyFirstClient.post("/api/refine-ui", { foo: "bar" }) + ).rejects.toThrow("HTTP 500 Internal Server Error: {\"error\":\"Anthropic experiencing high load\"}"); + }); + + it("throws on non-2xx response when response has no body", async () => { + const { twentyFirstClient } = await import("./http-client.js"); + + globalThis.fetch = async () => + new Response(null, { + status: 503, + statusText: "Service Unavailable", + }) as Response; + + await expect( + twentyFirstClient.post("/api/refine-ui", { foo: "bar" }) + ).rejects.toThrow("HTTP 503 Service Unavailable"); + }); + + it("throws on 401 with the error body from server", async () => { + const { twentyFirstClient } = await import("./http-client.js"); + + globalThis.fetch = async () => + new Response(JSON.stringify({ error: "Invalid or inactive API key" }), { + status: 401, + statusText: "Unauthorized", + }) as Response; + + await expect( + twentyFirstClient.get("/api/some-endpoint") + ).rejects.toThrow("HTTP 401 Unauthorized: {\"error\":\"Invalid or inactive API key\"}"); + }); +}); \ No newline at end of file diff --git a/src/utils/http-client.ts b/src/utils/http-client.ts index 66ce62a..a0bf58e 100644 --- a/src/utils/http-client.ts +++ b/src/utils/http-client.ts @@ -59,6 +59,14 @@ const createMethod = (method: HttpMethod) => { }); console.log("response", response); + + if (!response.ok) { + const errorText = await response.text().catch(() => ""); + throw new Error( + `HTTP ${response.status} ${response.statusText}${errorText ? `: ${errorText}` : ""}` + ); + } + return { status: response.status, data: (await response.json()) as T }; }; };