mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-01 18:13:39 +00:00
The error handler in tryHandleRootHelpFastPath only set process.exitCode=1 without calling process.exit(). When dangling async handles exist (timers, connections, promises), the Node event loop stays open and the CLI hangs indefinitely instead of returning to the terminal. In tryHandleRootVersionFastPath, the default onError handler called process.exit(1) directly, bypassing the injected exit seam that the success path already uses. Changed to exit(1) (deps.exit ?? process.exit) so tests and embedded callers can observe and control exit on failure. Added rejection-path tests for version fast path: injected exit called on resolveVersion rejection, and caller-supplied onError honored. Fixes #97793. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
55 lines
1.7 KiB
TypeScript
55 lines
1.7 KiB
TypeScript
// Handles fast version output before the full CLI graph loads.
|
|
import { isRootVersionInvocation } from "./cli/argv.js";
|
|
import { resolveCliContainerTarget } from "./cli/container-target.js";
|
|
|
|
export function tryHandleRootVersionFastPath(
|
|
argv: string[],
|
|
deps: {
|
|
env?: NodeJS.ProcessEnv;
|
|
moduleUrl?: string;
|
|
output?: (message: string) => void;
|
|
exit?: (code?: number) => void;
|
|
onError?: (error: unknown) => void;
|
|
resolveVersion?: () => Promise<{
|
|
VERSION: string;
|
|
resolveCommitHash: (params: { moduleUrl: string }) => string | null;
|
|
}>;
|
|
} = {},
|
|
): boolean {
|
|
if (resolveCliContainerTarget(argv, deps.env)) {
|
|
return false;
|
|
}
|
|
if (!isRootVersionInvocation(argv)) {
|
|
return false;
|
|
}
|
|
const output = deps.output ?? ((message: string) => console.log(message));
|
|
const exit = deps.exit ?? ((code?: number) => process.exit(code));
|
|
const onError =
|
|
deps.onError ??
|
|
((error: unknown) => {
|
|
console.error(
|
|
"[openclaw] Failed to resolve version:",
|
|
error instanceof Error ? (error.stack ?? error.message) : error,
|
|
);
|
|
exit(1);
|
|
});
|
|
const resolveVersion =
|
|
deps.resolveVersion ??
|
|
(async () => {
|
|
const [{ VERSION }, { resolveCommitHash }] = await Promise.all([
|
|
import("./version.js"),
|
|
import("./infra/git-commit.js"),
|
|
]);
|
|
return { VERSION, resolveCommitHash };
|
|
});
|
|
|
|
resolveVersion()
|
|
.then(({ VERSION, resolveCommitHash }) => {
|
|
const commit = resolveCommitHash({ moduleUrl: deps.moduleUrl ?? import.meta.url });
|
|
output(commit ? `OpenClaw ${VERSION} (${commit})` : `OpenClaw ${VERSION}`);
|
|
exit(0);
|
|
})
|
|
.catch(onError);
|
|
return true;
|
|
}
|