Skip to content

Commit

Permalink
Make ruff-server panic hook more error resilient
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaReiser committed Aug 1, 2024
1 parent a3e67ab commit 1ff2f9b
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 8 deletions.
9 changes: 7 additions & 2 deletions crates/ruff/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,19 @@ pub fn main() -> ExitCode {
Err(err) => {
#[allow(clippy::print_stderr)]
{
use std::io::Write;

// Use `writeln` instead of `eprintln` to avoid panicking when the stderr pipe is broken.
let mut stderr = std::io::stderr().lock();

// This communicates that this isn't a linter error but ruff itself hard-errored for
// some reason (e.g. failed to resolve the configuration)
eprintln!("{}", "ruff failed".red().bold());
writeln!(stderr, "{}", "ruff failed".red().bold()).ok();
// Currently we generally only see one error, but e.g. with io errors when resolving
// the configuration it is help to chain errors ("resolving configuration failed" ->
// "failed to read file: subdir/pyproject.toml")
for cause in err.chain() {
eprintln!(" {} {cause}", "Cause:".bold());
writeln!(stderr, " {} {cause}", "Cause:".bold()).ok();
}
}
ExitStatus::Error.into()
Expand Down
14 changes: 8 additions & 6 deletions crates/ruff_server/src/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ pub(crate) fn init_messenger(client_sender: ClientSender) {

// When we panic, try to notify the client.
std::panic::set_hook(Box::new(move |panic_info| {
use std::io::Write;

if let Some(messenger) = MESSENGER.get() {
let _ = messenger.send(lsp_server::Message::Notification(
lsp_server::Notification {
Expand All @@ -33,12 +35,12 @@ pub(crate) fn init_messenger(client_sender: ClientSender) {

let backtrace = std::backtrace::Backtrace::force_capture();
tracing::error!("{panic_info}\n{backtrace}");
#[allow(clippy::print_stderr)]
{
// we also need to print to stderr directly in case tracing hasn't
// been initialized.
eprintln!("{panic_info}\n{backtrace}");
}

// we also need to print to stderr directly in case tracing hasn't
// been initialized.
// But use `writeln` instead of `eprintln` to avoid panicking when the stderr pipe is broken.
let mut stderr = std::io::stderr().lock();
writeln!(stderr, "{panic_info}\n{backtrace}").ok();
}));
}

Expand Down

0 comments on commit 1ff2f9b

Please sign in to comment.