Skip to content

iter-145: route click JS exceptions through the JSON error envelope - #185

Merged
ractive merged 5 commits into
mainfrom
iter-145/error-envelope-completeness
Aug 12, 2026
Merged

iter-145: route click JS exceptions through the JSON error envelope#185
ractive merged 5 commits into
mainfrom
iter-145/error-envelope-completeness

Conversation

@ractive

@ractive ractive commented Aug 12, 2026

Copy link
Copy Markdown
Owner

Summary

  • click.rs's two remaining bare-stderr-then-AppError::Exit(1) paths (a genuine JS exception thrown during click, at the top-level attempt and inside the frame-scan retry) now route through the standard JSON error envelope (error_type: "User") via a shared classify_click_exception() helper — the same treatment eval.rs got in iter-141 Theme E.
  • Audited every eprintln! under crates/ff-rdp-cli/src/commands/ (~42 sites). Found one more instance of the same bug class in scroll.rs's "scroll until" timeout (now AppError::Timeout, matching every other timeout in the codebase). The remaining ~40 sites are legitimately stderr (progress/debug/warn-and-continue) — annotating them is deferred to kb/iterations/iteration-148-stderr-path-annotations.md per iter-145's own escape hatch.
  • Added a new xtask gate, check-error-envelope-paths, that fails when an eprintln! in crates/ff-rdp-cli/src/commands/ is immediately followed by a bare AppError::Exit(N) bypass — wired into check-iteration-ready (now 11/11 sub-checks) and the discipline CI job, so this defect class can't silently reappear.
  • Docs: CONTRIBUTING.md's gate list updated; iteration plan ACs ticked with evidence.

Test plan

  • cargo fmt / cargo clippy --workspace --all-targets -- -D warnings / cargo test --workspace -q all clean
  • cargo run -p xtask -- check-iteration-ready --plan kb/iterations/iteration-145-error-envelope-completeness.md --base origin/main → 11/11 PASS (run with FF_RDP_LIVE_TESTS=1 so check-dogfood-script executes)
  • New live tests run against real headless Firefox over the default daemon path (FF_RDP_LIVE_TESTS=1 cargo test -p ff-rdp-cli --test live live_145 -- --include-ignored): live_145_click_js_exception_envelope, live_145_click_frame_scan_js_exception_envelope, live_145_click_element_not_found_unchanged — all pass
  • New unit tests: unit_145_click_exception_maps_to_user_error_type + classify_click_exception coverage in click.rs
  • cargo run -p xtask -- check-error-envelope-paths passes on this branch (and its own unit tests cover the bug shape it's designed to catch, including a miniature of the pre-fix click.rs pattern)

🤖 Generated with Claude Code## Claims vs code
<generated 2026-08-12T08:05:46Z by ralph-loop>

  • a → ✅ matched in diff
  • AppError::Exit → ✅ matched in diff
  • AppError::User → ✅ matched in diff
  • AppError::Timeout → ✅ matched in diff
  • frame-scan → ✅ matched in diff

ractive and others added 5 commits August 12, 2026 09:57
click.rs's two remaining bare-stderr-then-AppError::Exit(1) paths (a
genuine JS exception during click, at the top-level attempt and inside
the frame-scan retry) now route through AppError::User via a shared
classify_click_exception() helper, matching eval.rs's iter-141 Theme E
handling. The audit also found scroll.rs's "scroll until" timeout using
the same bare-stderr-then-Exit(1) bypass; reclassified to
AppError::Timeout.

Adds a new xtask gate, check-error-envelope-paths, that fails CI when an
eprintln! in crates/ff-rdp-cli/src/commands/ is immediately followed by
a bare AppError::Exit(N) bypassing the envelope — wired into
check-iteration-ready and the discipline CI job.

The remaining ~40 eprintln! sites audited are legitimately stderr
(progress/debug/warn-and-continue); annotating them with justification
comments is deferred to iteration-148-stderr-path-annotations.md per
iter-145's own escape hatch.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ac-fidelity-check.sh only parses the first physical line of a checkbox;
the backtick-quoted error_type/Internal evidence for
unit_145_click_exception_maps_to_user_error_type was on the wrapped
continuation line, so the check reported no evidence despite the test
existing. Reflow to one line — no content change.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… test

The aggregator's sub-check count moved to 11/11 in this PR (iter-145 added
check-error-envelope-paths) and the assertion condition was updated to
match, but the panic message text still said "[{i}/10]" — found during
/review-pr local pass.
…test flake

iter-145 added a sixth live_145_* test file reusing the shared LiveFirefox
teardown in tests/common/mod.rs, so Theme A's fix covers it automatically —
no AC changes needed, just a note confirming coverage and flagging the
firefox_with_daemon duplication as a follow-up candidate.

Also record a one-off flaky unit-test race hit during iter-145's review
(specs::types::tests::resolve_slot_longstring_grip_fetches_full_value racing
transport.rs's FRAME_CAP_LOCK-guarded tests) — a different bug class than
this plan's live-Firefox themes, noted so it isn't lost rather than folded
into Theme A/B/C.
@ractive
ractive merged commit a75d231 into main Aug 12, 2026
10 checks passed
@ractive
ractive deleted the iter-145/error-envelope-completeness branch August 12, 2026 09:08
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