Skip to content

fix(cli): single structured error and correct exit code on input failure#123

Open
rmyndharis wants to merge 1 commit into
google-labs-code:mainfrom
rmyndharis:fix/cli-error-output
Open

fix(cli): single structured error and correct exit code on input failure#123
rmyndharis wants to merge 1 commit into
google-labs-code:mainfrom
rmyndharis:fix/cli-error-output

Conversation

@rmyndharis

Copy link
Copy Markdown

Summary

Two related fixes to CLI error reporting.

1. Missing/unreadable input printed a duplicate error and the wrong exit code

readInput (used by lint, diff, export) printed a clean FILE_READ_ERROR JSON to stderr, then re-threw the underlying error. The throw propagated to the CLI framework, which printed a second error — including a readFileSync stack trace — on top of the JSON, and exited with code 1 even though the code set process.exitCode = 2.

Reproduction (before): design.md lint missing.md → two stderr blocks (JSON + ERROR ENOENT … at readFileSync …), exit 1.

Fix: process.exit(2) immediately after writing the JSON. This matches the function's own JSDoc ("exits with error JSON"), removes the duplicate stack-trace output, and uses a dedicated I/O exit code (2) distinct from lint-findings (1).

2. Inconsistent stderr error envelope

readInput emits { error: "<CODE>", message, path }, but export emitted { error: "<free-text message>" } and discarded the structured code that emitters already return (e.g. INVALID_TOKEN_NAME).

Fix: export now emits { error: "<CODE>", message }INVALID_FORMAT for an unknown --format, and the emitter's own code forwarded on emitter failure.

Behavior change

Exit code on a missing/unreadable input file goes from 1 → 2 (the value the code already intended). lint/diff/export are affected; the 0/1 lint-findings contract is unchanged.

Testing

  • New commands/cli-errors.test.ts (spawns the CLI): missing file → exit 2 with exactly one JSON line (FILE_READ_ERROR, no stack trace); unknown export format → exit 1 with INVALID_FORMAT.
  • bun test: 284 pass, 1 skip, 0 fail. bun run lint: clean.
  • Verified against the built CLI: missing file → exit 2, single JSON; emitter failure → { "error": "INVALID_TOKEN_NAME", "message": … }.

…on input failure

On a missing or unreadable input file, readInput printed a structured
FILE_READ_ERROR JSON to stderr and then re-threw. The throw let the CLI
framework print a second, stack-trace error on top of the JSON and override
the exit code with 1 instead of the intended 2. Exit cleanly with code 2
right after the JSON, matching the function's documented "exits with error
JSON" contract.

Also unify the export command's stderr error envelope with readInput's
`{ error: <CODE>, message }` shape: an unknown --format now reports
`INVALID_FORMAT` (the human text moves to `message`), and emitter failures
forward the emitter's structured code (e.g. INVALID_TOKEN_NAME) instead of
discarding it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant