Skip to content

Commit f178917

Browse files
committed
fix: handle JSON.stringify edge cases in stringifyUnknown
Wrap JSON.stringify in try/catch to gracefully handle circular references and BigInt values. Falls back to String() which is always safe. Add tests for both edge cases. Addresses Cursor BugBot feedback on PR #259.
1 parent dee2294 commit f178917

File tree

2 files changed

+22
-1
lines changed

2 files changed

+22
-1
lines changed

src/lib/errors.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,13 @@ export function stringifyUnknown(value: unknown): string {
330330
return value.message;
331331
}
332332
if (value && typeof value === "object") {
333-
return JSON.stringify(value);
333+
// JSON.stringify can throw on circular references or BigInt values.
334+
// Fall back to String() which is always safe.
335+
try {
336+
return JSON.stringify(value);
337+
} catch {
338+
return String(value);
339+
}
334340
}
335341
return String(value);
336342
}

test/lib/errors.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,21 @@ describe("stringifyUnknown", () => {
291291
expect(stringifyUnknown(true)).toBe("true");
292292
expect(stringifyUnknown(0)).toBe("0");
293293
});
294+
295+
test("falls back to String() for circular references", () => {
296+
const circular: Record<string, unknown> = { name: "loop" };
297+
circular.self = circular;
298+
// Should not throw — falls back to String() which returns [object Object]
299+
expect(() => stringifyUnknown(circular)).not.toThrow();
300+
expect(stringifyUnknown(circular)).toBe("[object Object]");
301+
});
302+
303+
test("falls back to String() for BigInt values", () => {
304+
const obj = { count: BigInt(42) };
305+
// JSON.stringify throws on BigInt — should fall back gracefully
306+
expect(() => stringifyUnknown(obj)).not.toThrow();
307+
expect(stringifyUnknown(obj)).toBe("[object Object]");
308+
});
294309
});
295310

296311
describe("formatError", () => {

0 commit comments

Comments
 (0)