From 96e7f3f96f21d0ab32a11ae10d90049f5547f3ef Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Mon, 23 Sep 2024 09:48:43 -0400 Subject: [PATCH] Exit gracefully on broken pipe errors (#13485) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Closes https://github.com/astral-sh/ruff/issues/13483. Closes https://github.com/astral-sh/ruff/issues/13442. ## Test Plan ``` ❯ cargo run analyze graph ../django | head -n 10 Compiling ruff v0.6.7 (/Users/crmarsh/workspace/ruff/crates/ruff) Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.63s Running `target/debug/ruff analyze graph ../django` warning: `ruff analyze graph` is experimental and may change without warning { "/Users/crmarsh/workspace/django/django/__init__.py": [ "/Users/crmarsh/workspace/django/django/apps/__init__.py", "/Users/crmarsh/workspace/django/django/conf/__init__.py", "/Users/crmarsh/workspace/django/django/urls/__init__.py", "/Users/crmarsh/workspace/django/django/utils/log.py", "/Users/crmarsh/workspace/django/django/utils/version.py" ], "/Users/crmarsh/workspace/django/django/__main__.py": [ "/Users/crmarsh/workspace/django/django/core/management/__init__.py" ``` --- crates/ruff/src/main.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/crates/ruff/src/main.rs b/crates/ruff/src/main.rs index 27b2fad53e505..8be939671d33d 100644 --- a/crates/ruff/src/main.rs +++ b/crates/ruff/src/main.rs @@ -3,6 +3,7 @@ use std::process::ExitCode; use clap::{Parser, Subcommand}; use colored::Colorize; use log::error; +use std::io::Write; use ruff::args::{Args, Command}; use ruff::{run, ExitStatus}; @@ -86,7 +87,16 @@ pub fn main() -> ExitCode { Ok(code) => code.into(), Err(err) => { { - use std::io::Write; + // Exit "gracefully" on broken pipe errors. + // + // See: https://github.com/BurntSushi/ripgrep/blob/bf63fe8f258afc09bae6caa48f0ae35eaf115005/crates/core/main.rs#L47C1-L61C14 + for cause in err.chain() { + if let Some(ioerr) = cause.downcast_ref::() { + if ioerr.kind() == std::io::ErrorKind::BrokenPipe { + return ExitCode::from(0); + } + } + } // Use `writeln` instead of `eprintln` to avoid panicking when the stderr pipe is broken. let mut stderr = std::io::stderr().lock();