Google API errors as typed findings, never raw JSON: cli/lib/google-errors.ts parses SERVICE_DISABLED (api-disabled: service, Cloud project, console page), PERMISSION_DENIED (no-app-access: which app, Users and permissions), 401 / invalid_grant (auth-revoked) and 429 (quota); health / analytics print one line with the URL, raw text in detail and the log; desktop Health tab: the line, 'Turn it on in Google Cloud' and 'Check again', raw text in a collapsed Details; Portfolio shows a Cloud project blocking several apps once. Findings exit codes are results: the sidecar reports outcome (ok / findings / declined / failed) and the command's own error line; scan / check / validate / health exit 1 with findings show and cache the findings; no bare 'Exit code N' anywhere. tests/google-errors.test.ts, boot check errors cases (api-disabled, scan-findings, scan-failed) (pitfall 57)
This commit is contained in:
parent
f69c10d3a0
commit
89256f1e80
28 changed files with 666 additions and 47 deletions
|
|
@ -69,6 +69,48 @@ export interface ToolResult {
|
|||
output: string;
|
||||
/** Structured result of a --json capable command. */
|
||||
data?: unknown;
|
||||
/** What the exit code means: 0 = ok; a documented findings code with the --json result printed (scan / check /
|
||||
* validate / health exit 1 when they find problems) = findings; 3 = declined; anything else = failed. Missing in
|
||||
* results cached by older versions (outcomeOf below decides then). */
|
||||
outcome?: Outcome;
|
||||
/** failed only: the command's own error line (stderr's last "error: ..." line, else its last meaningful line). */
|
||||
error?: string;
|
||||
}
|
||||
|
||||
export type Outcome = 'ok' | 'findings' | 'declined' | 'failed';
|
||||
/** Read tools whose exit code 1 means "found problems" (the result is still printed with --json): by design, so CI fails. */
|
||||
export const FINDINGS_EXIT: Readonly<Record<string, readonly number[]>> = {
|
||||
scan: [1], check: [1], validate: [1], health: [1], check_aso: [1], shots_check: [1], catalog_diff: [1], aso_audit: [1],
|
||||
};
|
||||
/** lib/ctx DECLINED_EXIT: the owner's answer was missing or "no". */
|
||||
export const DECLINED_CODE = 3;
|
||||
|
||||
/** The outcome of a run (`tool`: the MCP tool name or the desktop method, dots or underscores). */
|
||||
export function outcomeOf(tool: string, code: number, hasData: boolean): Outcome {
|
||||
if (code === 0) return 'ok';
|
||||
if (code === DECLINED_CODE) return 'declined';
|
||||
if (hasData && (FINDINGS_EXIT[tool.replace(/\./g, '_')] ?? []).includes(code)) return 'findings';
|
||||
return 'failed';
|
||||
}
|
||||
|
||||
/** Is this line noise rather than a message (blank, a stack frame, a lone brace, a usage line)? */
|
||||
const noise = (l: string): boolean => !l.trim() || /^\s+at\s/.test(l) || /^[\s{}[\](),;]*$/.test(l) || /^\s*(usage|options|examples?):/i.test(l) || /^\s{2,}--?\w/.test(l);
|
||||
/** A log line without its "12:00:00 [tag] " prefix. */
|
||||
const bare = (l: string): string => l.trim().replace(/^\d\d:\d\d:\d\d \[[^\]]+\] /, '').replace(/^\S+ \[[^\]]+\] /, '');
|
||||
|
||||
/**
|
||||
* The command's own error line: the last "error: ..." line of stderr (the CLI's top-level catch), else the first
|
||||
* meaningful stderr line (unknown command / option: the message comes before the usage), else the last meaningful
|
||||
* output line. '' when the command said nothing. Pure.
|
||||
*/
|
||||
export function errorLine(stderr: string, output = ''): string {
|
||||
const err = stderr.split('\n');
|
||||
const tagged = err.filter(l => /^\s*error:\s*\S/i.test(bare(l))).at(-1);
|
||||
if (tagged) return bare(tagged).replace(/^error:\s*/i, '').slice(0, 500);
|
||||
const first = err.find(l => !noise(l));
|
||||
if (first) return bare(first).slice(0, 500);
|
||||
const last = output.split('\n').filter(l => !noise(l)).at(-1);
|
||||
return last ? bare(last).slice(0, 500) : '';
|
||||
}
|
||||
|
||||
export interface ProgressParams { requestId: string | number; line?: string; stream?: 'stdout' | 'stderr'; n?: number; total?: number; project?: string }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue