Skip to content

Commit 1ff2f9b

Browse files
committed
Make ruff-server panic hook more error resilient
1 parent a3e67ab commit 1ff2f9b

File tree

2 files changed

+15
-8
lines changed

2 files changed

+15
-8
lines changed

crates/ruff/src/main.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,14 +87,19 @@ pub fn main() -> ExitCode {
8787
Err(err) => {
8888
#[allow(clippy::print_stderr)]
8989
{
90+
use std::io::Write;
91+
92+
// Use `writeln` instead of `eprintln` to avoid panicking when the stderr pipe is broken.
93+
let mut stderr = std::io::stderr().lock();
94+
9095
// This communicates that this isn't a linter error but ruff itself hard-errored for
9196
// some reason (e.g. failed to resolve the configuration)
92-
eprintln!("{}", "ruff failed".red().bold());
97+
writeln!(stderr, "{}", "ruff failed".red().bold()).ok();
9398
// Currently we generally only see one error, but e.g. with io errors when resolving
9499
// the configuration it is help to chain errors ("resolving configuration failed" ->
95100
// "failed to read file: subdir/pyproject.toml")
96101
for cause in err.chain() {
97-
eprintln!(" {} {cause}", "Cause:".bold());
102+
writeln!(stderr, " {} {cause}", "Cause:".bold()).ok();
98103
}
99104
}
100105
ExitStatus::Error.into()

crates/ruff_server/src/message.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ pub(crate) fn init_messenger(client_sender: ClientSender) {
1616

1717
// When we panic, try to notify the client.
1818
std::panic::set_hook(Box::new(move |panic_info| {
19+
use std::io::Write;
20+
1921
if let Some(messenger) = MESSENGER.get() {
2022
let _ = messenger.send(lsp_server::Message::Notification(
2123
lsp_server::Notification {
@@ -33,12 +35,12 @@ pub(crate) fn init_messenger(client_sender: ClientSender) {
3335

3436
let backtrace = std::backtrace::Backtrace::force_capture();
3537
tracing::error!("{panic_info}\n{backtrace}");
36-
#[allow(clippy::print_stderr)]
37-
{
38-
// we also need to print to stderr directly in case tracing hasn't
39-
// been initialized.
40-
eprintln!("{panic_info}\n{backtrace}");
41-
}
38+
39+
// we also need to print to stderr directly in case tracing hasn't
40+
// been initialized.
41+
// But use `writeln` instead of `eprintln` to avoid panicking when the stderr pipe is broken.
42+
let mut stderr = std::io::stderr().lock();
43+
writeln!(stderr, "{panic_info}\n{backtrace}").ok();
4244
}));
4345
}
4446

0 commit comments

Comments
 (0)