mirror of
https://github.com/sharkdp/hyperfine.git
synced 2026-11-01 17:00:18 +00:00
Handle broken pipe errors on stdout gracefully (#932)
Replace `println!` calls on the results paths with `writeln!` on `io::stdout()` and propagate the `io::Error` to `main`, where `ErrorKind::BrokenPipe` is turned into a quiet `exit(0)`. This matches the conventional behavior of command-line tools when their output pipe is closed early (e.g. `hyperfine ... | head -n 0`), and fixes panics in all run-output paths: the per-benchmark header and results, the speed comparison summary, and `-`-style exports to stdout. The warnings and "Note" outputs to stderr are converted the same way. --------- Co-authored-by: Mathjk <Mathjk@users.noreply.github.com> Co-authored-by: David Peter <mail@david-peter.de>
This commit is contained in:
7 files changed
+118
-30
No files matched your search
+16
-2
@@ -4,10 +4,12 @@
|
||||
)]
|
||||
|
||||
use std::env;
|
||||
use std::io::{self, Write};
|
||||
|
||||
use benchmark::scheduler::Scheduler;
|
||||
use cli::get_cli_arguments;
|
||||
use command::Commands;
|
||||
use error::ConsoleOutputError;
|
||||
use export::ExportManager;
|
||||
use options::Options;
|
||||
|
||||
@@ -44,17 +46,29 @@ fn run() -> Result<()> {
|
||||
|
||||
let mut scheduler = Scheduler::new(&commands, &options, &export_manager);
|
||||
scheduler.run_benchmarks()?;
|
||||
scheduler.print_relative_speed_comparison();
|
||||
scheduler.print_relative_speed_comparison()?;
|
||||
scheduler.final_export()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn caused_by_broken_console_pipe(error: &anyhow::Error) -> bool {
|
||||
error
|
||||
.downcast_ref::<ConsoleOutputError>()
|
||||
.is_some_and(|e| e.0.kind() == io::ErrorKind::BrokenPipe)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
match run() {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
eprintln!("{} {:#}", "Error:".red(), e);
|
||||
// Exit quietly when a reader stops consuming console output early.
|
||||
if caused_by_broken_console_pipe(&e) {
|
||||
std::process::exit(0);
|
||||
}
|
||||
// The write to stderr can itself fail if stderr is closed; the
|
||||
// error message cannot be shown in that case anyway.
|
||||
let _ = writeln!(io::stderr(), "{} {:#}", "Error:".red(), e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user