Skip to content

refactor(errors): finish routing command-failure bails through CommandError - #3483

Merged
max-sixty merged 2 commits into
mainfrom
normalize-stdout-cr
Jul 15, 2026
Merged

refactor(errors): finish routing command-failure bails through CommandError#3483
max-sixty merged 2 commits into
mainfrom
normalize-stdout-cr

Conversation

@max-sixty

@max-sixty max-sixty commented Jul 15, 2026

Copy link
Copy Markdown
Owner

Follow-up to #3474: converts the remaining raw-output bail!("{stderr}") sites to typed CommandError, so every failed-command display goes through the one normalizing constructor (\r stripping, canonical ✗ <command> failed (exit N) header + output gutter).

Sites converted:

  • step/shared.rs (git ls-files in ignored-entry listing) and step/commit.rs (git add into the temp index) — the two commands-layer git sites.
  • The five claude/codex plugin CLI calls in commands/config/{plugins,codex}.rs, collapsed into one private run_plugin_cli helper in commands/config/mod.rs. Their failure snapshots now show the canonical header + stderr gutter instead of ✗ claude plugin marketplace add failed: <stderr>.
  • execute_llm_command in llm.rs — its hand-rolled stderr/stdout/exit-code fallback ladder was from_failed_output's job; deleted in favor of the constructor. The LlmCommandFailed wrappers read the detail via ErrorExt::display_message(), which extracts the captured output for command failures and matches the old text in the common cases; the picker summary pane guards on the error type (format_summary_error) — command failures surface their captured output, everything else keeps the full anyhow chain the pane always showed (folded in from review). The shell program is recorded by basename only (same rule as render_llm_invocation), so a no-output failure doesn't leak the Git Bash install path on Windows.

Deliberately left: the two gh pr list / glab mr list bails in picker/prs.rs. Their consumer is the skim-footer warning sink where the current one-line text is the intended display, and picker text sanitization was explicitly dropped (#3177).

Behavior note (intended, but visible): an LLM command that emits on both streams before failing now shows both in the error block (combined_output() joins stderr + stdout); the old ladder showed stderr only.

Testing: three new error-path unit tests (list_ignored_entries / stage_to_temp_index via corrupt-config and bad-pathspec, execute_llm_command exit-code + basename assertion); the five plugin sites are covered by the existing failing-mock integration tests whose snapshots this updates; test_generate_summary_llm_error covers the summary-pane command-failure arm and format_summary_error_keeps_chain_for_non_command_errors the chain-preserving arm.

This was written by Claude Code on behalf of max

…dError

The remaining raw-stderr bail sites all become CommandError so failed-command
display has one constructor (\r-normalized, typed command/output split):

- step/shared.rs ls-files and step/commit.rs stage-to-temp-index (git)
- claude/codex plugin CLI calls, collapsed into one run_plugin_cli helper
  in commands/config — their failure snapshots pick up the canonical
  header + gutter rendering
- execute_llm_command: the stderr/stdout/exit-code fallback ladder is
  from_failed_output's job; the LlmCommandFailed wrappers and the picker
  summary pane read the detail via display_message(), which extracts the
  captured output for command failures and falls back to the same
  outermost message as before for spawn errors

The gh/glab picker-list bails stay: their consumer is the skim footer,
where the current one-line text is the intended display and picker text
sanitization was deliberately dropped (#3177).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@worktrunk-bot worktrunk-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean refactor — the routing through CommandError::from_failed_output is correct, imports balance, and the three new error-path tests are deterministic and cross-platform (invalid pathspec / corrupt .git/config / sh -c all fail identically under sh and Git Bash). One non-blocking observation on the summary preview inline.

Comment thread src/summary.rs Outdated
display_message() collapses any non-CommandError to its outermost context
line, so the preview pane lost the cause chain for spawn failures and
template bugs, not just the narrow case the PR body flagged. Guard on the
error type instead: command failures surface their captured output,
everything else keeps the {:#} chain the pane always showed.

Suggested by the automated reviewer on #3483.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@max-sixty
max-sixty merged commit 612580b into main Jul 15, 2026
39 checks passed
@max-sixty
max-sixty deleted the normalize-stdout-cr branch July 15, 2026 21:30
max-sixty added a commit that referenced this pull request Jul 15, 2026
)

Step-12 drift fold for the v0.68.0 release: #3483 (the follow-up
completing #3474) merged during the release PR CI window, so it ships in
0.68.0 but the changelog entry only covered the eight #3474 sites. The
entry now covers the full cutover and cites #3483.

> _This was written by Claude Code on behalf of max_
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.

2 participants