Repository navigation
fix(cli): exit 1 when refactor target is not found - #275
Akshay0047 wants to merge 3 commits into
Conversation
Anandb71
left a comment
There was a problem hiding this comment.
Thanks for this, @Akshay0047, and welcome to Arbor! The write-up was easy to review: the root-cause explanation, the before/after test output and the scope notes all helped.
What I verified
- Built the PR head locally:
cargo fmt --all -- --checkis clean.cargo clippy -p arbor-graph-cli --all-targets --all-features -- -D warningsis clean.cargo test -p arbor-graph-cliis all green.
refactor_not_found_symbolfails against the pre-fixcommands.rsand passes with your change.- Ran the binary against a small fixture:
arbor refactor nonexistent_xyz .exits 1, keeps the hint on stdout and printserror: Symbol 'nonexistent_xyz' not foundon stderr. That's the same stderr message and exit code asinspectandcallers.- A symbol that exists behaves exactly as before: exit 0, and valid JSON with
--json.
main.rsis the only caller ofcommands::refactor. The Claude Code hook only allow-listsarbor refactor *, and neither receipts nor MCP run it as a subprocess, so agent workflows aren't affected.- It merges cleanly with current
main. - About your "note on behavior":
suggest_similar_symbolsnever actually returnsErr, so there's no old error precedence to keep. Returning the resolve error is the right call.
CI: Because this is your first PR from a fork, GitHub holds the Rust CI, PR Bot and Benchmarks runs until a maintainer approves them. That's why only GitGuardian shows up so far. We'll approve them.
Requested changes (both small)
-
--jsonon a missing symbol (crates/arbor-cli/src/commands.rs:2640-2644).arbor refactor nonexistent_xyz . --jsonstill prints the human-readable "Couldn't find … / Tips" block on stdout. A script doingarbor refactor "$SYM" --json | jqthen gets a parse error instead of empty stdout.inspect --jsonandcallers --jsonprint nothing on stdout in the same case. This predates your PR (it used to be that same text with exit 0), but it's the exact line you're editing. Could you gate the hint on!json_output?Err(e) => { if !json_output { let _ = suggest_similar_symbols(&graph, target); } return Err(e); }
Please also add a
--jsoncase to the test that asserts a non-zero exit and empty stdout. -
CHANGELOG. CONTRIBUTING asks for user-visible changes under
## [Unreleased], and a new exit code counts. Please rebase onmainfirst: 3.0.5 added a section right below[Unreleased], so an entry on the current base would conflict there. Something like:### Fixed - **`arbor refactor` exited 0 for a missing symbol (#195):** it now exits 1 and prints `error: Symbol '<name>' not found` to stderr after the "Did you mean" suggestions, matching `inspect` and `callers`.
Nits (optional)
- In
refactor_not_found_symbol, could you also assertstderr.contains("not found"), ascallers_not_found_symboldoes? Scripts depend on that line. - The description says
arbor refactor ""is unchanged. With this PR it also exits 1 (error: Symbol '' not found), which I think is the right outcome. It's just worth updating the description to match.
One follow-up on our side, not something this PR needs to do: the VS Code extension only shows stderr when arbor exits non-zero. So "Analyze Impact" on a typo will now say "Is Arbor installed?" and lose the "Did you mean" hints. We'll fix that separately.
Thanks again! Once those two changes are in and CI is green, this is good to merge.
Review feedback on Anandb71#195. When --json is set and the symbol is missing, arbor refactor still wrote the human-readable 'Couldn't find / Tips' block to stdout, so scripts piping to jq got a parse error instead of empty stdout. Gate the suggest_similar_symbols hint on !json_output. Add a --json case to refactor_not_found_symbol that asserts non-zero exit, empty stdout, and 'not found' on stderr. Also assert 'not found' on stderr in the non-json case, matching callers_not_found_symbol. CHANGELOG entry under [Unreleased].
6dcada5 to
9883bc0
Compare
|
Done @Anandb71 — both requested changes are in, plus the two nits.
Rebased on Thanks for the note about |
Anandb71
left a comment
There was a problem hiding this comment.
Thanks for the quick turnaround, @Akshay0047! The round-2 write-up was again very easy to follow.
Requested change 1 (--json on a missing symbol): done ✅
commands.rsnow gatessuggest_similar_symbolson!json_outputand returns the resolve error, exactly as suggested.- I built 9883bc0 and ran it against a small indexed fixture:
arbor refactor nonexistent_xyz . --jsonexits 1. Stdout is completely empty and stderr iserror: Symbol 'nonexistent_xyz' not found, so| jqno longer chokes.- Without
--json, it still prints the "Couldn't find / Tips" hint on stdout and exits 1. - An existing symbol with
--jsonexits 0 and prints valid JSON. arbor refactor "" .exits 1 witherror: Symbol '' not found, matching your updated description.
- The new
--jsoncase and thenot foundstderr assertions inrefactor_not_found_symbollook good, and the test passes. - Locally:
cargo fmt --all -- --checkis clean,cargo clippy -p arbor-graph-cli --all-targets --all-features -- -D warningsis clean, andcargo test -p arbor-graph-cliis all green. - It merges cleanly with
main(e10cb78).
Requested change 2 (CHANGELOG): one small fix still needed
The entry landed at CHANGELOG.md:36, at the end of the ## [3.0.4] ### Fixed list. ## [Unreleased] (line 8) is still empty. That's probably just the rebase moving it. As it stands, the next release notes would miss the fix, and 3.0.4 would appear to have shipped it. Could you move it up like this?
## [Unreleased]
### Fixed
- **`arbor refactor` exited 0 for a missing symbol (#195):** it now exits 1 and prints `error: Symbol '<name>' not found` to stderr after the "Did you mean" suggestions, matching `inspect` and `callers`.
## [3.0.5] - 2026-10-09If you'd rather, say so and we can move it while merging. "Allow edits by maintainers" is on.
CI
- GitHub is still holding the Rust CI, PR Bot and Benchmarks runs for this fork until a maintainer approves them. That's why only GitGuardian shows so far.
- That's on us: we'll approve them, and we'll merge once the CHANGELOG line is moved and those runs are green.
Thanks again, and welcome aboard!
The rebase on v3.0.5 changed which section was at the top of the file, so the entry landed inside [3.0.4] ### Fixed. Moved to [Unreleased] per review; the next release notes would have missed it otherwise.
|
Done @Anandb71 — moved the entry to Pushed as a small Thanks for catching it. Ready when CI is approved. |
Fixes #195.
arbor refactor <missing-symbol>exited 0.refactormappedresolve_symbol_ranked'sErrtoNoneand fell through tosuggest_similar_symbols, which prints a hint and returnsOk(()), somain.rsnever reached itsprocess::exit(1)path. Scripts and CI couldnot distinguish "refactor target exists" from "no such symbol."
The fix binds the original
Err(e)and returns it after still runningsuggest_similar_symbols(its return is discarded withlet _ =; thesuggestion output is deliberately preserved).
inspectandcallersalready propagate this error the same way, so the new exit code matches
existing convention.
Test
refactor_not_found_symbolincrates/arbor-cli/tests/graph_commands_integration.rs, next tocallers_not_found_symbol. Spawns the built binary, asserts non-zeroexit, and asserts the suggestion hint is still on stdout.
Verified failing on pre-fix code:
and passing after:
cargo fmt --all -- --checkandcargo clippy --workspace --all-targets --all-featuresare clean.Scope
arbor refactor ""(empty target) is unchanged — separate concern.query's swallow pattern is out of scope here; it isqueryexits 0 when there are no matches and on an empty query #196.Note on behavior
The previous code path had two matches and returned
suggest_similar_symbols's own error on failure; the new path alwaysreturns the
resolve_symbol_rankederror. Both exit 1 and both write tostderr, so user-visible behavior is unchanged, but flagging it in case a
reviewer wants the old precedence preserved.
Round 2 (review feedback)
suggest_similar_symbolshint on!json_output, soarbor refactor missing --jsonwrites nothing to stdout.--jsoncase torefactor_not_found_symbolthat assertsnon-zero exit, empty stdout, and
not foundon stderr.not foundassertion to the non-json case, matchingcallers_not_found_symbol.[Unreleased](rebased on main).arbor refactor ""now exits 1 too, whichis the intended behavior.