From 06f88ed7e8ec858fb2fd58f7817ac873c995da82 Mon Sep 17 00:00:00 2001 From: summer-tt Date: Wed, 28 Oct 2026 23:48:53 +0800 Subject: [PATCH] fix(stream): retain fallback for invalid queue wait hints --- src/__tests__/model-busy-retry.test.ts | 12 ++++++++++++ src/protocol/stream.ts | 7 +++++-- 2 files changed, 17 insertions(+), 2 deletions(-) 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) }; }