diff --git a/src/__tests__/model-busy-retry.test.ts b/src/__tests__/model-busy-retry.test.ts index 483e6e7..e99b7c0 100644 --- a/src/__tests__/model-busy-retry.test.ts +++ b/src/__tests__/model-busy-retry.test.ts @@ -198,6 +198,18 @@ describe("parseModelBusyRejection", () => { }); }); + it.each([1e300, Number.MAX_VALUE, Number.MAX_SAFE_INTEGER])( + "uses retryAfterSeconds when queue waitTime=%s exceeds safe milliseconds", + (waitTime) => { + expect(parseModelBusyRejection(busyBody({ isQueued: true, waitTime, retryAfterSeconds: 30 }))).toEqual({ + kind: "queued", + waitMs: 30000, + queueCount: 0, + queueType: "p4", + }); + }, + ); + it("rejects a queued snapshot without the service flags", () => { expect(parseModelBusyRejection(busyBody({ isQueued: true, serviceAvailable: undefined }))).toBeUndefined(); }); diff --git a/src/protocol/stream.ts b/src/protocol/stream.ts index d1c4455..f51a2c9 100644 --- a/src/protocol/stream.ts +++ b/src/protocol/stream.ts @@ -105,8 +105,11 @@ export function parseModelBusyRejection(body: unknown): ModelBusyQueueSnapshot | const queue = parseJsonObject(busy.message); if (!queue) return undefined; if (queue.serviceAvailable !== true) return undefined; - const seconds = (value: unknown): number => - typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.round(value * 1000) : 0; + const seconds = (value: unknown): number => { + if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) return 0; + const milliseconds = Math.round(value * 1000); + return Number.isSafeInteger(milliseconds) && milliseconds > 0 ? milliseconds : 0; + }; if (queue.isQueued === false) { return { kind: "ready", retryAfterMs: seconds(queue.retryAfterSeconds) }; }