mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-06 05:51:15 +08:00
Merge branch 'main' into policy-sandbox-posture-conformance
This commit is contained in:
@@ -543,6 +543,23 @@ describe("fetchBrowserJson loopback auth", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("uses the default timeout for non-finite absolute HTTP timeout failures", async () => {
|
||||
vi.stubGlobal(
|
||||
"fetch",
|
||||
vi.fn(async () => {
|
||||
throw new Error("timed out");
|
||||
}),
|
||||
);
|
||||
|
||||
await expectThrownBrowserFetchError(
|
||||
() => fetchBrowserJson<{ ok: boolean }>("http://example.com/", { timeoutMs: Number.NaN }),
|
||||
{
|
||||
contains: ["timed out after 5000ms"],
|
||||
omits: ["NaNms", "Do NOT retry the browser tool"],
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it("omits no-retry hint for absolute HTTP abort failures", async () => {
|
||||
vi.stubGlobal(
|
||||
"fetch",
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { parseFiniteNumber } from "openclaw/plugin-sdk/number-runtime";
|
||||
import { fetchWithSsrFGuard } from "openclaw/plugin-sdk/ssrf-runtime";
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
@@ -162,6 +163,11 @@ function appendBrowserToolModelHint(message: string): string {
|
||||
|
||||
type BrowserFetchFailureKind = "timeout" | "aborted" | "persistent";
|
||||
|
||||
function resolveBrowserFetchTimeoutMs(timeoutMs: number | undefined): number {
|
||||
const parsed = parseFiniteNumber(timeoutMs);
|
||||
return Math.max(1, Math.floor(parsed ?? 5000));
|
||||
}
|
||||
|
||||
function classifyBrowserFetchFailure(err: unknown): BrowserFetchFailureKind {
|
||||
const msg = normalizeErrorMessage(err);
|
||||
const msgLower = normalizeLowercaseStringOrEmpty(msg);
|
||||
@@ -228,7 +234,7 @@ async function fetchHttpJson<T>(
|
||||
url: string,
|
||||
init: RequestInit & { timeoutMs?: number },
|
||||
): Promise<T> {
|
||||
const timeoutMs = init.timeoutMs ?? 5000;
|
||||
const timeoutMs = resolveBrowserFetchTimeoutMs(init.timeoutMs);
|
||||
const ctrl = new AbortController();
|
||||
const upstreamSignal = init.signal;
|
||||
let upstreamAbortListener: (() => void) | undefined;
|
||||
@@ -278,7 +284,7 @@ export async function fetchBrowserJson<T>(
|
||||
url: string,
|
||||
init?: RequestInit & { timeoutMs?: number },
|
||||
): Promise<T> {
|
||||
const timeoutMs = init?.timeoutMs ?? 5000;
|
||||
const timeoutMs = resolveBrowserFetchTimeoutMs(init?.timeoutMs);
|
||||
let isDispatcherPath = false;
|
||||
try {
|
||||
if (isAbsoluteHttp(url)) {
|
||||
|
||||
Reference in New Issue
Block a user