fix(cli): suppress bug-report banner on broken pipe print panics (#34552)
## Summary
Fixes denoland/deno#16308.
When stdout/stderr is piped to a process that closes the pipe early —
e.g. `deno | cls` on Windows, the example from the issue — Rust's
`println!`/`eprintln!` macros panic with `failed printing to stdout: The
pipe is being closed. (os error 232)`. The custom panic hook in
`cli/lib.rs` treated every panic as a Deno bug and emitted the "Deno has
panicked. This is a bug in Deno." banner, which is misleading and noisy.
The previous fix #21945 only made the REPL banner safe (replaced
`println!` with `writeln!(_, …)?`). Any subcommand that prints via
`println!`/`print!` (e.g. `deno info`, the REPL eval loop's
`println!("{}", output)`, the many tools under `cli/tools/` that use
`print!`) still panicked with the bug-report banner.
This change adds a check at the top of the panic hook: if the panic
payload is one of std's print-macro panics (`failed printing to
{stdout,stderr}: …`) AND the message contains a broken-pipe OS error
code (EPIPE=32 on Unix, ERROR_BROKEN_PIPE=109 / ERROR_NO_DATA=232 on
Windows), exit cleanly with status 1 instead of printing the bug-report
banner. The detection is precise, so unrelated panics still surface the
bug-report banner as before.
## Test plan
- Added `broken_stdout_no_panic_banner` integration test that pipes
`deno info` to a closed reader and asserts that stderr contains neither
`Deno has panicked` nor `panicked at`. Without the fix the test fails
because the `println!` calls in `print_cache_info` trigger the
bug-report banner.
- Existing `broken_stdout_repl` test continues to pass (REPL banner
still uses safe `writeln!?` and surfaces the error via `log::error!`, so
stderr still contains the expected `Broken pipe (os error 32)` / `The
pipe is being closed. (os error 232)` strings).
- Existing `stdout_early_read_drop` test continues to pass (`deno eval`
/ `console.log` already routes through `op_print` which swallows
`BrokenPipe`).
- Existing `tests/specs/test/recursive_permissions_pledge` continues to
pass (its panic is not a broken-pipe print panic, so the hook still
emits the bug-report banner as expected).
Closes denoland/orchid#305
Co-authored-by: divybot <divybot@users.noreply.github.com>
Co-authored-by: Divy Srivastava <me@littledivy.com>