Skip to content

Commit 351d056

Browse files
committed
fix(update): centralize timeout seconds parsing
1 parent e098fd4 commit 351d056

2 files changed

Lines changed: 7 additions & 9 deletions

File tree

src/cli/update-cli/shared.command-runner.test.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,15 @@ describe("createGlobalCommandRunner", () => {
5757
try {
5858
expect(parseTimeoutMsOrExit("1.5")).toBeNull();
5959
expect(parseTimeoutMsOrExit("10abc")).toBeNull();
60+
expect(parseTimeoutMsOrExit("0x10")).toBeNull();
6061
expect(parseTimeoutMsOrExit("0")).toBeNull();
6162
expect(parseTimeoutMsOrExit("-1")).toBeNull();
6263
expect(parseTimeoutMsOrExit(" ")).toBeNull();
6364
expect(parseTimeoutMsOrExit(String(Number.MAX_SAFE_INTEGER))).toBeNull();
6465

65-
expect(error).toHaveBeenCalledTimes(6);
66+
expect(error).toHaveBeenCalledTimes(7);
6667
expect(error).toHaveBeenCalledWith("--timeout must be a positive integer (seconds)");
67-
expect(exit).toHaveBeenCalledTimes(6);
68+
expect(exit).toHaveBeenCalledTimes(7);
6869
expect(exit).toHaveBeenCalledWith(1);
6970
} finally {
7071
error.mockRestore();
@@ -78,6 +79,7 @@ describe("createGlobalCommandRunner", () => {
7879

7980
try {
8081
expect(parseTimeoutMsOrExit(" 10 ")).toBe(10_000);
82+
expect(parseTimeoutMsOrExit("+10")).toBe(10_000);
8183
expect(parseTimeoutMsOrExit("001")).toBe(1_000);
8284
expect(parseTimeoutMsOrExit()).toBeUndefined();
8385
expect(error).not.toHaveBeenCalled();

src/cli/update-cli/shared.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { resolveRequiredHomeDir } from "../../infra/home-dir.js";
66
import { resolveOpenClawPackageRoot } from "../../infra/openclaw-root.js";
77
import { readPackageName, readPackageVersion } from "../../infra/package-json.js";
88
import { normalizePackageTagInput } from "../../infra/package-tag.js";
9+
import { parseStrictPositiveInteger } from "../../infra/parse-finite-number.js";
910
import { trimLogTail } from "../../infra/restart-sentinel.js";
1011
import { parseSemver } from "../../infra/runtime-guard.js";
1112
import { fetchNpmTagVersion } from "../../infra/update-check.js";
@@ -60,13 +61,8 @@ export function parseTimeoutMsOrExit(timeout?: string): number | undefined | nul
6061
return undefined;
6162
}
6263
const trimmed = timeout.trim();
63-
const seconds = Number(trimmed);
64-
if (
65-
!/^\d+$/u.test(trimmed) ||
66-
!Number.isSafeInteger(seconds) ||
67-
seconds <= 0 ||
68-
seconds > MAX_SAFE_TIMEOUT_SECONDS
69-
) {
64+
const seconds = parseStrictPositiveInteger(trimmed);
65+
if (seconds === undefined || seconds > MAX_SAFE_TIMEOUT_SECONDS) {
7066
defaultRuntime.error(INVALID_TIMEOUT_ERROR);
7167
defaultRuntime.exit(1);
7268
return null;

0 commit comments

Comments
 (0)