fix(ui): preserve Gateway opening timeout diagnostics (#117078)

Co-authored-by: Peter Steinberger <steipete@macos.shared>
This commit is contained in:
Peter Steinberger
2026-07-31 17:14:30 -07:00
committed by GitHub
parent a1c689e375
commit e857d8e5c6
2 changed files with 20 additions and 10 deletions
+14 -1
View File
@@ -76,7 +76,20 @@ describe("createBrowserGatewaySocket", () => {
socket?.emit("error");
socket?.emit("close", { code: 1006, reason: "" });
expect(handlers.error).toHaveBeenCalledOnce();
expect(handlers.close).toHaveBeenCalledWith(1006, "");
expect(handlers.close).toHaveBeenCalledWith(
1006,
`gateway websocket opening timed out after ${DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS}ms`,
);
});
it("preserves a real close reason when an opening timeout also occurred", async () => {
const handlers = createHandlers();
createBrowserGatewaySocket("wss://gateway.example", handlers);
await vi.advanceTimersByTimeAsync(DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS);
sockets[0]?.emit("close", { code: 1006, reason: "gateway supplied a close reason" });
expect(handlers.close).toHaveBeenCalledWith(1006, "gateway supplied a close reason");
});
it("clears the opening deadline after the socket opens", async () => {
+6 -9
View File
@@ -10,7 +10,7 @@ export function createBrowserGatewaySocket(
): GatewayProtocolSocket {
const socket = new WebSocket(url);
let opening = true;
let openingTimedOut = false;
let openingTimeoutReason: string | undefined;
let openingTimer: ReturnType<typeof setTimeout> | undefined;
const finishOpening = () => {
opening = false;
@@ -27,11 +27,12 @@ export function createBrowserGatewaySocket(
socket.addEventListener("message", (event) => handlers.message(String(event.data ?? "")));
socket.addEventListener("close", (event) => {
finishOpening();
handlers.close(event.code, event.reason ?? "");
// Browsers erase locally initiated close reasons before the handshake finishes.
handlers.close(event.code, event.reason || openingTimeoutReason || "");
});
socket.addEventListener("error", () => {
finishOpening();
if (!openingTimedOut) {
if (!openingTimeoutReason) {
handlers.error(new Error("websocket error"));
}
});
@@ -44,13 +45,9 @@ export function createBrowserGatewaySocket(
return;
}
opening = false;
openingTimedOut = true;
openingTimeoutReason = `gateway websocket opening timed out after ${DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS}ms`;
try {
handlers.error(
new Error(
`gateway websocket opening timed out after ${DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS}ms`,
),
);
handlers.error(new Error(openingTimeoutReason));
} finally {
socket.close();
}