diff --git a/src/gateway/client.ts b/src/gateway/client.ts index ad28d5ea4f5..61dc4728627 100644 --- a/src/gateway/client.ts +++ b/src/gateway/client.ts @@ -121,6 +121,7 @@ export function describeGatewayCloseCode(code: number): string | undefined { const FORCE_STOP_TERMINATE_GRACE_MS = 250; const STOP_AND_WAIT_TIMEOUT_MS = 1_000; +const DEFAULT_CONNECT_CHALLENGE_TIMEOUT_MS = 5_000; type PendingStop = { ws: WebSocket; @@ -701,7 +702,7 @@ export class GatewayClient { const connectChallengeTimeoutMs = typeof rawConnectDelayMs === "number" && Number.isFinite(rawConnectDelayMs) ? Math.max(250, Math.min(10_000, rawConnectDelayMs)) - : 2_000; + : DEFAULT_CONNECT_CHALLENGE_TIMEOUT_MS; if (this.connectTimer) { clearTimeout(this.connectTimer); } diff --git a/src/gateway/client.watchdog.test.ts b/src/gateway/client.watchdog.test.ts index 603c36a229b..15deb90f783 100644 --- a/src/gateway/client.watchdog.test.ts +++ b/src/gateway/client.watchdog.test.ts @@ -36,6 +36,49 @@ describe("GatewayClient", () => { } }); + test("uses a 5s default connect-challenge timeout", async () => { + vi.useFakeTimers(); + try { + const onConnectError = vi.fn(); + const close = vi.fn(); + const client = new GatewayClient({ onConnectError }); + ( + client as unknown as { + ws: + | WebSocket + | { + readyState: number; + send: () => void; + close: (code: number, reason: string) => void; + }; + queueConnect: () => void; + } + ).ws = { + readyState: WebSocket.OPEN, + send: vi.fn(), + close, + }; + + ( + client as unknown as { + queueConnect: () => void; + } + ).queueConnect(); + + await vi.advanceTimersByTimeAsync(4_999); + expect(onConnectError).not.toHaveBeenCalled(); + expect(close).not.toHaveBeenCalled(); + + await vi.advanceTimersByTimeAsync(1); + expect(onConnectError).toHaveBeenCalledWith( + expect.objectContaining({ message: "gateway connect challenge timeout" }), + ); + expect(close).toHaveBeenCalledWith(1008, "connect challenge timeout"); + } finally { + vi.useRealTimers(); + } + }); + test("closes on missing ticks", async () => { const port = await getFreePort(); wss = new WebSocketServer({ port, host: "127.0.0.1" });