mirror of
https://github.com/morluto/rea
synced 2026-10-26 06:16:17 -04:00
fix(electron): report rejected CLI arguments with issue details (#5036)
* fix(electron): report rejected CLI arguments with issue details Pass schema validation issues and submitted input to inputError in list-electron-targets and inspect-electron-page commands, matching the structured diagnostics returned by browser commands. Fixes #3865 * test(electron): assert exit code 1 on rejected CLI arguments
This commit is contained in:
@@ -217,10 +217,16 @@ const registerElectronTargetList = (
|
||||
withCommandCancellation((signal) =>
|
||||
logCliCommand(logger, "list-electron-targets", async () => {
|
||||
const context = await electronObservationContext();
|
||||
const parsed = listElectronTargetsInputSchema.safeParse({
|
||||
const input = {
|
||||
cdp_endpoint: args.endpoint,
|
||||
});
|
||||
if (!parsed.success) return inputError("list_electron_targets");
|
||||
};
|
||||
const parsed = listElectronTargetsInputSchema.safeParse(input);
|
||||
if (!parsed.success)
|
||||
return inputError(
|
||||
"list_electron_targets",
|
||||
parsed.error.issues,
|
||||
input,
|
||||
);
|
||||
const { listElectronTargets } =
|
||||
await import("../application/javascript/ElectronObservationService.js");
|
||||
return await finishAnalysisCommand(
|
||||
@@ -255,13 +261,19 @@ const registerElectronPageInspection = (
|
||||
withCommandCancellation((signal) =>
|
||||
logCliCommand(logger, "inspect-electron-page", async () => {
|
||||
const context = await electronObservationContext();
|
||||
const parsed = inspectElectronPageInputSchema.safeParse({
|
||||
const input = {
|
||||
cdp_endpoint: args.endpoint,
|
||||
target_id: args.targetId,
|
||||
observation_ms: options.observationMs,
|
||||
include_script_sources: options.includeScriptSources,
|
||||
});
|
||||
if (!parsed.success) return inputError("inspect_electron_page");
|
||||
};
|
||||
const parsed = inspectElectronPageInputSchema.safeParse(input);
|
||||
if (!parsed.success)
|
||||
return inputError(
|
||||
"inspect_electron_page",
|
||||
parsed.error.issues,
|
||||
input,
|
||||
);
|
||||
const { inspectElectronPage } =
|
||||
await import("../application/javascript/ElectronObservationService.js");
|
||||
return await finishAnalysisCommand(
|
||||
|
||||
@@ -96,6 +96,53 @@ it(
|
||||
INTEGRATION_TEST_TIMEOUT_MS,
|
||||
);
|
||||
|
||||
it(
|
||||
"reports rejected Electron CLI arguments with structured issue details",
|
||||
async () => {
|
||||
const invalidTargetList = await runCliResult(
|
||||
["list-electron-targets", "not a url", "--json"],
|
||||
process.env,
|
||||
);
|
||||
expect(invalidTargetList.exitCode).toBe(1);
|
||||
expect(invalidTargetList.result).toMatchObject({
|
||||
error: "Electron analysis failed",
|
||||
code: "invalid_request",
|
||||
category: "invalid_input",
|
||||
details: {
|
||||
operation: "list_electron_targets",
|
||||
issues: [
|
||||
{
|
||||
path: ["cdp_endpoint"],
|
||||
reason: "invalid_value",
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const invalidPageInspect = await runCliResult(
|
||||
["inspect-electron-page", "http://127.0.0.1:9222", "", "--json"],
|
||||
process.env,
|
||||
);
|
||||
expect(invalidPageInspect.exitCode).toBe(1);
|
||||
expect(invalidPageInspect.result).toMatchObject({
|
||||
error: "Electron analysis failed",
|
||||
code: "invalid_request",
|
||||
category: "invalid_input",
|
||||
details: {
|
||||
operation: "inspect_electron_page",
|
||||
issues: [
|
||||
{
|
||||
path: ["target_id"],
|
||||
reason: "out_of_range",
|
||||
minimum: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
},
|
||||
INTEGRATION_TEST_TIMEOUT_MS,
|
||||
);
|
||||
|
||||
// On Windows child.kill("SIGINT") terminates the process without a console signal.
|
||||
it.skipIf(process.platform === "win32")(
|
||||
"forwards SIGINT through Electron page inspection and completes target cleanup",
|
||||
@@ -436,25 +483,32 @@ describe("Electron CLI runtime reconciliation", () => {
|
||||
const isRecord = (value: unknown): value is Record<string, unknown> =>
|
||||
typeof value === "object" && value !== null && !Array.isArray(value);
|
||||
|
||||
const runCli = async (
|
||||
const runCliResult = async (
|
||||
arguments_: readonly string[],
|
||||
environment: NodeJS.ProcessEnv,
|
||||
): Promise<unknown> => {
|
||||
): Promise<{ readonly exitCode: number; readonly result: unknown }> => {
|
||||
try {
|
||||
const { stdout } = await execute(
|
||||
process.execPath,
|
||||
["scripts/rea.mjs", ...arguments_],
|
||||
{ cwd: process.cwd(), env: environment, maxBuffer: 16 * 1_024 * 1_024 },
|
||||
);
|
||||
return JSON.parse(stdout);
|
||||
return { exitCode: 0, result: JSON.parse(stdout) };
|
||||
} catch (cause: unknown) {
|
||||
if (
|
||||
typeof cause === "object" &&
|
||||
cause !== null &&
|
||||
"stdout" in cause &&
|
||||
typeof cause.stdout === "string"
|
||||
typeof cause.stdout === "string" &&
|
||||
"code" in cause &&
|
||||
typeof cause.code === "number"
|
||||
)
|
||||
return JSON.parse(cause.stdout);
|
||||
return { exitCode: cause.code, result: JSON.parse(cause.stdout) };
|
||||
throw cause;
|
||||
}
|
||||
};
|
||||
|
||||
const runCli = async (
|
||||
arguments_: readonly string[],
|
||||
environment: NodeJS.ProcessEnv,
|
||||
): Promise<unknown> => (await runCliResult(arguments_, environment)).result;
|
||||
|
||||
Reference in New Issue
Block a user