From 65167c963733ec3ff2e38d949de87e4a23847e54 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 30 May 2026 16:58:38 -0400 Subject: [PATCH] fix(tlon): clamp sse reconnect delays --- extensions/tlon/src/urbit/sse-client.test.ts | 11 +++++++++++ extensions/tlon/src/urbit/sse-client.ts | 5 +++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/extensions/tlon/src/urbit/sse-client.test.ts b/extensions/tlon/src/urbit/sse-client.test.ts index 673d8cd0d020..6487f481e1c7 100644 --- a/extensions/tlon/src/urbit/sse-client.test.ts +++ b/extensions/tlon/src/urbit/sse-client.test.ts @@ -1,3 +1,4 @@ +import { MAX_TIMER_TIMEOUT_MS } from "openclaw/plugin-sdk/number-runtime"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { urbitFetch } from "./fetch.js"; import { UrbitSSEClient } from "./sse-client.js"; @@ -137,6 +138,16 @@ describe("UrbitSSEClient", () => { expect(client.onReconnect).toBe(onReconnect); }); + it("clamps oversized reconnect delays", () => { + const client = new UrbitSSEClient("https://example.com", "urbauth-~zod=123", { + reconnectDelay: Number.MAX_SAFE_INTEGER, + maxReconnectDelay: Number.MAX_SAFE_INTEGER, + }); + + expect(client.reconnectDelay).toBe(MAX_TIMER_TIMEOUT_MS); + expect(client.maxReconnectDelay).toBe(MAX_TIMER_TIMEOUT_MS); + }); + it("resets reconnect attempts on successful connect", async () => { const mockUrbitFetch = vi.mocked(urbitFetch); diff --git a/extensions/tlon/src/urbit/sse-client.ts b/extensions/tlon/src/urbit/sse-client.ts index d53c409096bd..ad801b3f445b 100644 --- a/extensions/tlon/src/urbit/sse-client.ts +++ b/extensions/tlon/src/urbit/sse-client.ts @@ -1,5 +1,6 @@ import { randomUUID } from "node:crypto"; import { Readable } from "node:stream"; +import { resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime"; import type { LookupFn, SsrFPolicy } from "openclaw/plugin-sdk/ssrf-runtime"; import { ensureUrbitChannelOpen, pokeUrbitChannel, scryUrbitPath } from "./channel-ops.js"; import { getUrbitContext, normalizeUrbitCookie } from "./context.js"; @@ -87,8 +88,8 @@ export class UrbitSSEClient { this.onReconnect = options.onReconnect ?? null; this.autoReconnect = options.autoReconnect !== false; this.maxReconnectAttempts = options.maxReconnectAttempts ?? 10; - this.reconnectDelay = options.reconnectDelay ?? 1000; - this.maxReconnectDelay = options.maxReconnectDelay ?? 30000; + this.reconnectDelay = resolveTimerTimeoutMs(options.reconnectDelay, 1000); + this.maxReconnectDelay = resolveTimerTimeoutMs(options.maxReconnectDelay, 30000); this.logger = options.logger ?? {}; this.ssrfPolicy = options.ssrfPolicy; this.lookupFn = options.lookupFn;