mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-27 21:07:01 -06:00
fix(cli): keep approvals JSON failures parseable (#124585)
This commit is contained in:
committed by
GitHub
parent
eafeeec537
commit
b5491a08bf
@@ -273,6 +273,19 @@ describe("exec approvals pending and resolve CLI", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("writes pending approval failures as JSON", async () => {
|
||||
callGatewayFromCli.mockRejectedValue(new Error("gateway unavailable"));
|
||||
|
||||
await expect(runApprovalsCommand(["approvals", "pending", "--json"])).rejects.toThrow(
|
||||
"__exit__:1",
|
||||
);
|
||||
|
||||
expect(defaultRuntime.writeJson).toHaveBeenCalledOnce();
|
||||
expect(defaultRuntime.writeJson).toHaveBeenCalledWith({ error: "gateway unavailable" }, 0);
|
||||
expect(defaultRuntime.error).not.toHaveBeenCalled();
|
||||
expect(defaultRuntime.exit).toHaveBeenCalledWith(1);
|
||||
});
|
||||
|
||||
it("preserves whitespace-bearing ids verbatim and keeps them distinct", async () => {
|
||||
const now = Date.now();
|
||||
callGatewayFromCli.mockImplementation(async (method: string) => {
|
||||
|
||||
@@ -945,7 +945,8 @@ describe("exec approvals CLI", () => {
|
||||
|
||||
await expect(runNativeApprovalsFileCommand(filePath)).rejects.toThrow("__exit__:1");
|
||||
|
||||
expect(runtimeErrors[0]).toContain("File exceeds 1048576 bytes");
|
||||
expect(writtenJson().error).toContain("File exceeds 1048576 bytes");
|
||||
expect(runtimeErrors).toHaveLength(0);
|
||||
expect(callGatewayFromCli).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
@@ -954,7 +955,8 @@ describe("exec approvals CLI", () => {
|
||||
|
||||
await expect(runNativeApprovalsFileCommand(dir)).rejects.toThrow("__exit__:1");
|
||||
|
||||
expect(runtimeErrors[0]).toMatch(/EISDIR|directory/i);
|
||||
expect(writtenJson().error).toMatch(/EISDIR|directory/i);
|
||||
expect(runtimeErrors).toHaveLength(0);
|
||||
expect(callGatewayFromCli).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
@@ -990,7 +992,8 @@ describe("exec approvals CLI", () => {
|
||||
openSpy.mockRestore();
|
||||
}
|
||||
|
||||
expect(runtimeErrors[0]).toContain("File exceeds 1048576 bytes");
|
||||
expect(writtenJson().error).toContain("File exceeds 1048576 bytes");
|
||||
expect(runtimeErrors).toHaveLength(0);
|
||||
expect(callGatewayFromCli).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -302,8 +302,6 @@ async function loadSnapshotTarget(opts: ExecApprovalsCliOpts): Promise<{
|
||||
}
|
||||
|
||||
function exitWithError(message: string): never {
|
||||
defaultRuntime.error(message);
|
||||
defaultRuntime.exit(1);
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
@@ -382,6 +380,16 @@ function formatCliError(err: unknown): string {
|
||||
return safe.length > 300 ? `${truncateUtf16Safe(safe, 300)}...` : safe;
|
||||
}
|
||||
|
||||
function failApprovalsCommand(err: unknown, opts: ExecApprovalsCliOpts): void {
|
||||
const message = formatCliError(err);
|
||||
if (opts.json) {
|
||||
defaultRuntime.writeJson({ error: message }, 0);
|
||||
} else {
|
||||
defaultRuntime.error(message);
|
||||
}
|
||||
defaultRuntime.exit(1);
|
||||
}
|
||||
|
||||
function isApprovalDecision(value: string): value is ApprovalDecision {
|
||||
return (APPROVAL_DECISIONS as readonly string[]).includes(value);
|
||||
}
|
||||
@@ -1082,8 +1090,7 @@ async function runAllowlistMutation(
|
||||
targetLabel: context.targetLabel,
|
||||
});
|
||||
} catch (err) {
|
||||
defaultRuntime.error(formatCliError(err));
|
||||
defaultRuntime.exit(1);
|
||||
failApprovalsCommand(err, opts);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1132,8 +1139,7 @@ export function registerExecApprovalsCli(program: Command) {
|
||||
}
|
||||
renderPendingApprovals(entries);
|
||||
} catch (err) {
|
||||
defaultRuntime.error(formatCliError(err));
|
||||
defaultRuntime.exit(1);
|
||||
failApprovalsCommand(err, opts);
|
||||
}
|
||||
});
|
||||
nodesCallOpts(pendingCmd);
|
||||
@@ -1146,8 +1152,7 @@ export function registerExecApprovalsCli(program: Command) {
|
||||
try {
|
||||
await resolvePendingApproval(id, decision, opts);
|
||||
} catch (err) {
|
||||
defaultRuntime.error(formatCliError(err));
|
||||
defaultRuntime.exit(1);
|
||||
failApprovalsCommand(err, opts);
|
||||
}
|
||||
});
|
||||
nodesCallOpts(resolveCmd);
|
||||
@@ -1187,8 +1192,7 @@ export function registerExecApprovalsCli(program: Command) {
|
||||
renderApprovalsSnapshot(snapshot, targetLabel);
|
||||
renderEffectivePolicy({ report: effectivePolicy });
|
||||
} catch (err) {
|
||||
defaultRuntime.error(formatCliError(err));
|
||||
defaultRuntime.exit(1);
|
||||
failApprovalsCommand(err, opts);
|
||||
}
|
||||
});
|
||||
nodesCallOpts(getCmd, { timeoutMs: APPROVALS_GET_DEFAULT_TIMEOUT_MS });
|
||||
@@ -1236,8 +1240,7 @@ export function registerExecApprovalsCli(program: Command) {
|
||||
file.version = 1;
|
||||
await saveSnapshotTargeted({ opts, source, nodeId, file, baseHash, targetLabel });
|
||||
} catch (err) {
|
||||
defaultRuntime.error(formatCliError(err));
|
||||
defaultRuntime.exit(1);
|
||||
failApprovalsCommand(err, opts);
|
||||
}
|
||||
});
|
||||
nodesCallOpts(setCmd);
|
||||
|
||||
Reference in New Issue
Block a user