From 118f3f3312e429427433b09a87cb952b4e3c8489 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Sat, 20 Jun 2026 06:18:53 +0200 Subject: [PATCH] fix(scripts): clear RPC RTT send failure timers --- scripts/measure-rpc-rtt.mjs | 17 +++++++++-------- test/scripts/measure-rpc-rtt.test.ts | 24 ++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/scripts/measure-rpc-rtt.mjs b/scripts/measure-rpc-rtt.mjs index cc7515c256da..361e86c2097b 100644 --- a/scripts/measure-rpc-rtt.mjs +++ b/scripts/measure-rpc-rtt.mjs @@ -720,18 +720,19 @@ export function createGatewayClient({ WebSocket, openTimeoutMs = 8_000, url }) { reject(new Error(`timeout waiting for ${method}`)); }, timeoutMs); pending.set(id, { resolve, reject, timeout }); - ws.send(JSON.stringify({ type: "req", id, method, params }), (error) => { + const rejectSendFailure = (error) => { if (!error) { return; } - const waiter = pending.get(id); - if (!waiter) { - return; - } pending.delete(id); - clearTimeout(waiter.timeout); - waiter.reject(error instanceof Error ? error : new Error(String(error))); - }); + clearTimeout(timeout); + reject(error instanceof Error ? error : new Error(String(error))); + }; + try { + ws.send(JSON.stringify({ type: "req", id, method, params }), rejectSendFailure); + } catch (error) { + rejectSendFailure(error); + } }); const close = () => { rejectPending(new Error("gateway websocket client closed")); diff --git a/test/scripts/measure-rpc-rtt.test.ts b/test/scripts/measure-rpc-rtt.test.ts index 89a11cdd6fb8..be2ad601f0d7 100644 --- a/test/scripts/measure-rpc-rtt.test.ts +++ b/test/scripts/measure-rpc-rtt.test.ts @@ -102,6 +102,30 @@ describe("scripts/measure-rpc-rtt.mjs", () => { expect(socket.closed).toBe(true); }); + it("clears pending websocket request timers when send throws synchronously", async () => { + vi.useFakeTimers(); + FakeWebSocket.instances = []; + const client = createGatewayClient({ + WebSocket: FakeWebSocket, + url: "ws://127.0.0.1:12345", + }); + const socket = FakeWebSocket.instances[0]; + if (!socket) { + throw new Error("fake websocket was not created"); + } + socket.readyState = FakeWebSocket.OPEN; + socket.send = () => { + throw new Error("socket closed during send"); + }; + + await expect(client.request("health", {}, 10_000)).rejects.toThrow( + "socket closed during send", + ); + + expect(vi.getTimerCount()).toBe(0); + client.close(); + }); + it("parses bounded RPC RTT options strictly", () => { expect( parseArgs([