Answer a reader that went away, rather than panicking at it - #38
Conversation
Closes #37. `uphold rules --effective | head -2` exited 101, and so did every other subcommand piped into anything that stops reading: `println!` unwraps its write and panics, and Rust ignores SIGPIPE at startup, so a closed pipe arrives at the macro as an ordinary EPIPE rather than killing the process the way a shell expects. 114 print sites across 18 files reached it. 101 is not one of the three codes this tool promises, out of a binary installed in front of `git`, `gh` and `npm` -- and the run had already decided its verdict by the time the write failed. A crash loses that verdict and names `stdio.rs` at a reader who can act on neither. `report.rs` carries the same sentence about an earlier version of this, where a panic replaced the report the run existed to produce. Two answers, because the two failures are not the same thing: * **The reader went away.** Nothing is wrong with the run and nothing more will be read, so the rest of the output is dropped and the exit code stays the verdict. `head` closing a pipe is a reader's decision, not a check that could not be made. Asked once per stream and remembered, so a report with thousands of findings does not make thousands of failed syscalls. * **The write failed for any other reason** -- a full disk under a redirected report, a file this process may no longer write. There the output really did not arrive, and that is exit 2 by the rule that governs every other could-not-look here. `main` reads the first such error on the way out, because a caller holding half a file must not read 0 as a clean tree. Reached by shadowing `println!`, `print!` and `eprintln!` in `main.rs` rather than by a helper function beside them. A helper is a rule that 114 call sites have to remember and that the next line of code can silently break -- the same shape as a hand-copied rule, and invisible in exactly the same way. What cannot be forgotten is the spelling everybody already types. `eprint!` is shadowed too though nothing spells it yet, under an `#[expect(unused_macros)]` that turns the first use into a build error pointing at the line to delete. Both cases are tested at the CLI, where the only evidence is the process's exit status, and both were driven the other way first: with the macros removed they fail with `Some(101)` -- the pipe case on `rules --sets --json` and on `scan`, the unwritable-report case through `/dev/full`, which is skipped out loud where that device is not there. Claude-Session: https://claude.ai/code/session_01Dm334jAm9MP19Yzqq6Cua8
|
Warning Review limit reached
Next review available in: 15 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report❌ Patch coverage is
❌ Your patch status has failed because the patch coverage (96.77%) is below the target coverage (100.00%). You can increase the patch coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## main #38 +/- ##
==========================================
+ Coverage 89.40% 89.44% +0.04%
==========================================
Files 30 31 +1
Lines 9670 9732 +62
==========================================
+ Hits 8645 8705 +60
- Misses 1025 1027 +2 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Closes #37.
uphold rules --effective | head -2exited 101, and so did every other subcommand piped into anything that stops reading.println!unwraps its write and panics, and Rust ignoresSIGPIPEat startup, so a closed pipe arrives at the macro as an ordinaryEPIPErather than killing the process the way a shell expects. 114 print sites across 18 files reached it.101 is not one of the three codes this tool promises, out of a binary installed in front of
git,ghandnpm-- and the run had already decided its verdict by the time the write failed.uphold rules --effective | head -2uphold scan | head -1, tree with a violationuphold rules --effective > /dev/fullTwo answers, because the two failures are not the same thing:
2by the rule that governs every other could-not-look here. A caller holding half a file must not read0as a clean tree.Why a shadowed macro rather than a helper function. A helper is a rule that 114 call sites have to remember and that the next line of code can silently break -- the same shape as a hand-copied rule, and invisible in the same way. What cannot be forgotten is the spelling everybody already types, so
println!,print!andeprintln!are shadowed inmain.rsahead of the module list, where amacro_rules!is in scope for everything that follows it.eprint!is shadowed too though nothing spells it yet, under an#[expect(unused_macros)]that turns the first use into a build error pointing at the line to delete.src/out.rsis now the only place in the crate that touches either stream.Checks
Both cases are tested at the CLI, where the only evidence is the process's exit status, and both were driven the other way first: with the macros removed they fail with
Some(101). The/dev/fullcase is skipped out loud where that device is not there.prek run --all-files --hook-stage manualpasses, coverage floor included.cargo mutants --file src/out.rs: 10 mutants, 0 missed.https://claude.ai/code/session_01Dm334jAm9MP19Yzqq6Cua8