From a3ed9fe95506529494895f71321c5332583ad2ba Mon Sep 17 00:00:00 2001 From: Wilfred Hughes Date: Wed, 8 May 2024 16:38:06 -0700 Subject: [PATCH] fix: Report both IO errors and main_loop errors If rust-analyzer receives a malformed LSP request, the IO thread terminates with a meaningful error, but then closes the channel. Once the channel has closed, the main_loop also terminates, but it only has RecvError and can't show a meaningful error. As a result, rust-analyzer would incorrectly claim that the client forgot to shutdown. ``` $ buggy_lsp_client | rust-analyzer Error: client exited without proper shutdown sequence ``` Instead, include both error messages when the server shuts down. --- .../rust-analyzer/crates/rust-analyzer/src/bin/main.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs index 78920f3abace..9daae914d79c 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs @@ -259,9 +259,15 @@ fn run_server() -> anyhow::Result<()> { config.rediscover_workspaces(); } - rust_analyzer::main_loop(config, connection)?; + // If the io_threads have an error, there's usually an error on the main + // loop too because the channels are closed. Ensure we report both errors. + match (rust_analyzer::main_loop(config, connection), io_threads.join()) { + (Err(loop_e), Err(join_e)) => anyhow::bail!("{loop_e}\n{join_e}"), + (Ok(_), Err(join_e)) => anyhow::bail!("{join_e}"), + (Err(loop_e), Ok(_)) => anyhow::bail!("{loop_e}"), + (Ok(_), Ok(_)) => {} + } - io_threads.join()?; tracing::info!("server did shut down"); Ok(()) }