Skip to content

Commit 57a7979

Browse files
committed
Fix serialization issue
1 parent bba3bff commit 57a7979

2 files changed

Lines changed: 47 additions & 6 deletions

File tree

src/FetchClient.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -566,12 +566,14 @@ export class FetchClient {
566566
let bodyText = "";
567567
try {
568568
bodyText = await response.text();
569-
if (options.reviver || options.shouldParseDates) {
570-
data = JSON.parse(bodyText, (key, value) => {
571-
return this.reviveJsonValue(options, key, value);
572-
});
573-
} else {
574-
data = JSON.parse(bodyText);
569+
if (bodyText) {
570+
if (options.reviver || options.shouldParseDates) {
571+
data = JSON.parse(bodyText, (key, value) => {
572+
return this.reviveJsonValue(options, key, value);
573+
});
574+
} else {
575+
data = JSON.parse(bodyText);
576+
}
575577
}
576578
} catch (error: unknown) {
577579
data = new ProblemDetails();

src/tests/ErrorHandling.test.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,45 @@ Deno.test("handles 400 response with non-JSON text", async () => {
181181
);
182182
});
183183

184+
Deno.test("handles 403 with empty body without deserialization error", async () => {
185+
const mocks = new MockRegistry();
186+
mocks.onPost("/api/resource").reply(403);
187+
188+
const client = new FetchClient();
189+
mocks.install(client);
190+
191+
// Should throw FetchClientError with status-based message, not a deserialization error
192+
const error = await assertRejects(async () => {
193+
await client.postJSON("https://example.com/api/resource", {});
194+
}, FetchClientError);
195+
196+
assert(error instanceof FetchClientError);
197+
assertEquals(error.status, 403);
198+
assert(error.response.problem);
199+
assertEquals(error.response.problem.status, 403);
200+
assertStringIncludes(error.message, "Forbidden");
201+
// Should NOT contain deserialization error
202+
assertFalse(error.message.includes("Unable to deserialize"));
203+
});
204+
205+
Deno.test("handles empty body error response with expectedStatusCodes", async () => {
206+
const mocks = new MockRegistry();
207+
mocks.onGet("/api/resource").reply(403);
208+
209+
const client = new FetchClient();
210+
mocks.install(client);
211+
212+
const res = await client.getJSON("https://example.com/api/resource", {
213+
expectedStatusCodes: [403],
214+
});
215+
216+
assertFalse(res.ok);
217+
assertEquals(res.status, 403);
218+
assert(res.problem);
219+
// Problem title should not mention deserialization failure
220+
assertFalse(res.problem.title?.includes("Unable to deserialize") ?? false);
221+
});
222+
184223
Deno.test("network error throws TypeError", async () => {
185224
const mocks = new MockRegistry();
186225
mocks.onGet("/api/flaky").networkError("Connection refused");

0 commit comments

Comments
 (0)