mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-27 21:07:01 -06:00
* fix(cli): surface nested fetch failure details * fix(cli): preserve error prefixes in runtime output
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
// CLI utility tests cover shared command helpers, option parsing, and output formatting.
|
||||
import { Command } from "commander";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { runCommandWithRuntime } from "./cli-utils.js";
|
||||
import { registerDnsCli } from "./dns-cli.js";
|
||||
import { parseByteSize } from "./parse-bytes.js";
|
||||
import { parseDurationMs } from "./parse-duration.js";
|
||||
@@ -33,6 +34,33 @@ describe("waitForever", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("runCommandWithRuntime", () => {
|
||||
it("surfaces cause chains and error codes through the default runtime", async () => {
|
||||
const messages: string[] = [];
|
||||
const exits: number[] = [];
|
||||
const cause = Object.assign(new Error("invalid onRequestStart method"), {
|
||||
code: "UND_ERR_INVALID_ARG",
|
||||
});
|
||||
const fetchError = Object.assign(new TypeError("fetch failed"), { cause });
|
||||
|
||||
await runCommandWithRuntime(
|
||||
{
|
||||
error: (message) => messages.push(message),
|
||||
exit: (code) => exits.push(code),
|
||||
},
|
||||
async () => {
|
||||
throw fetchError;
|
||||
},
|
||||
);
|
||||
|
||||
expect(messages).toHaveLength(1);
|
||||
expect(messages[0]).toContain("TypeError: fetch failed");
|
||||
expect(messages[0]).toContain("invalid onRequestStart method");
|
||||
expect(messages[0]).toContain("UND_ERR_INVALID_ARG");
|
||||
expect(exits).toEqual([1]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("shouldSkipRespawnForArgv", () => {
|
||||
it.each([
|
||||
{ argv: ["node", "openclaw", "--help"] },
|
||||
|
||||
@@ -32,6 +32,13 @@ export async function withManager<T>(params: {
|
||||
}
|
||||
}
|
||||
|
||||
function formatCommandRuntimeError(err: unknown): string {
|
||||
if (err instanceof Error) {
|
||||
return formatErrorMessage(new Error(String(err), { cause: err.cause }));
|
||||
}
|
||||
return formatErrorMessage(err);
|
||||
}
|
||||
|
||||
export async function runCommandWithRuntime(
|
||||
runtime: { error: (message: string) => void; exit: (code: number) => void },
|
||||
action: () => Promise<void>,
|
||||
@@ -44,7 +51,7 @@ export async function runCommandWithRuntime(
|
||||
onError(err);
|
||||
return;
|
||||
}
|
||||
runtime.error(String(err));
|
||||
runtime.error(formatCommandRuntimeError(err));
|
||||
runtime.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,6 +86,10 @@ export function formatErrorMessage(err: unknown): string {
|
||||
seen.add(cause);
|
||||
if (cause instanceof Error) {
|
||||
appendCauseMessage(cause.message);
|
||||
const code = extractErrorCode(cause);
|
||||
if (code) {
|
||||
appendCauseMessage(code);
|
||||
}
|
||||
cause = cause.cause;
|
||||
} else if (typeof cause === "string") {
|
||||
appendCauseMessage(cause);
|
||||
|
||||
Reference in New Issue
Block a user