fix(browser): cap control fetch timeouts · openclaw/openclaw@5230a23
steipete
·
2026-05-30
·
via Recent Commits to openclaw:main
| Original file line number | Diff line number | Diff line change |
|---|
|
| 1 | +import { MAX_TIMER_TIMEOUT_MS } from "openclaw/plugin-sdk/number-runtime"; |
1 | 2 | import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; |
2 | 3 | import "../test-support/browser-security.mock.js"; |
3 | 4 | import type { OpenClawConfig } from "../config/config.js"; |
@@ -576,6 +577,31 @@ describe("fetchBrowserJson loopback auth", () => {
|
576 | 577 | ); |
577 | 578 | }); |
578 | 579 | |
| 580 | +it("caps oversized absolute HTTP timeouts before arming the watchdog", async () => { |
| 581 | +const timeoutSpy = vi |
| 582 | +.spyOn(globalThis, "setTimeout") |
| 583 | +.mockReturnValue(1 as unknown as ReturnType<typeof setTimeout>); |
| 584 | +vi.spyOn(globalThis, "clearTimeout").mockImplementation(() => undefined); |
| 585 | +vi.stubGlobal( |
| 586 | +"fetch", |
| 587 | +vi.fn(async () => { |
| 588 | +throw new Error("timed out"); |
| 589 | +}), |
| 590 | +); |
| 591 | + |
| 592 | +await expectThrownBrowserFetchError( |
| 593 | +() => |
| 594 | +fetchBrowserJson<{ ok: boolean }>("http://example.com/", { |
| 595 | +timeoutMs: Number.MAX_SAFE_INTEGER, |
| 596 | +}), |
| 597 | +{ |
| 598 | +contains: [`timed out after ${MAX_TIMER_TIMEOUT_MS}ms`], |
| 599 | +omits: ["Do NOT retry the browser tool"], |
| 600 | +}, |
| 601 | +); |
| 602 | +expect(timeoutSpy).toHaveBeenCalledWith(expect.any(Function), MAX_TIMER_TIMEOUT_MS); |
| 603 | +}); |
| 604 | + |
579 | 605 | it("omits no-retry hint for absolute HTTP abort failures", async () => { |
580 | 606 | vi.stubGlobal( |
581 | 607 | "fetch", |
|
| Original file line number | Diff line number | Diff line change |
|---|
|
1 | 1 | import { parseBrowserHttpUrl } from "openclaw/plugin-sdk/browser-config"; |
2 | | -import { parseFiniteNumber } from "openclaw/plugin-sdk/number-runtime"; |
| 2 | +import { resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime"; |
3 | 3 | import { fetchWithSsrFGuard } from "openclaw/plugin-sdk/ssrf-runtime"; |
4 | 4 | import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime"; |
5 | 5 | import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime"; |
@@ -159,8 +159,7 @@ function appendBrowserToolModelHint(message: string): string {
|
159 | 159 | type BrowserFetchFailureKind = "timeout" | "aborted" | "persistent"; |
160 | 160 | |
161 | 161 | function resolveBrowserFetchTimeoutMs(timeoutMs: number | undefined): number { |
162 | | -const parsed = parseFiniteNumber(timeoutMs); |
163 | | -return Math.max(1, Math.floor(parsed ?? 5000)); |
| 162 | +return resolveTimerTimeoutMs(timeoutMs, 5000); |
164 | 163 | } |
165 | 164 | |
166 | 165 | function classifyBrowserFetchFailure(err: unknown): BrowserFetchFailureKind { |
|
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。