Exit a language server if it sends a message with invalid json (#9332)

* Keep lsp event listener thread alive when malformed json is encountered from the lsp server

* Update unexpected error flow in recv() to close outstanding requests and close the language server

* Log malformed notifications as info instead of error

* Make close_language_server a nested function inside recv, similar to what's done in send

* Update malformed notification log text

* Clean up new log text a bit

* Initialize recv_buffer closer to where it's used

* Use "exit" instead of "close"

* Remove whitespace

* Remove the need for a helper method to exit the language server

* Match on Unhandled error explicitly and keep catch-all error case around
This commit is contained in:
Ben Dennis 2024-01-17 08:49:25 -06:00 committed by GitHub
parent f41727cc9c
commit dcdecaab22
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 15 additions and 8 deletions

View File

@ -270,7 +270,14 @@ async fn recv(
} }
}; };
} }
Err(Error::StreamClosed) => { Err(err) => {
if !matches!(err, Error::StreamClosed) {
error!(
"Exiting {} after unexpected error: {err:?}",
&transport.name
);
}
// Close any outstanding requests. // Close any outstanding requests.
for (id, tx) in transport.pending_requests.lock().await.drain() { for (id, tx) in transport.pending_requests.lock().await.drain() {
match tx.send(Err(Error::StreamClosed)).await { match tx.send(Err(Error::StreamClosed)).await {
@ -300,10 +307,6 @@ async fn recv(
} }
break; break;
} }
Err(err) => {
error!("{} err: <- {err:?}", transport.name);
break;
}
} }
} }
} }

View File

@ -27,7 +27,7 @@
ui::{self, overlay::overlaid}, ui::{self, overlay::overlaid},
}; };
use log::{debug, error, warn}; use log::{debug, error, info, warn};
#[cfg(not(feature = "integration"))] #[cfg(not(feature = "integration"))]
use std::io::stdout; use std::io::stdout;
use std::{collections::btree_map::Entry, io::stdin, path::Path, sync::Arc}; use std::{collections::btree_map::Entry, io::stdin, path::Path, sync::Arc};
@ -683,9 +683,13 @@ macro_rules! language_server {
Call::Notification(helix_lsp::jsonrpc::Notification { method, params, .. }) => { Call::Notification(helix_lsp::jsonrpc::Notification { method, params, .. }) => {
let notification = match Notification::parse(&method, params) { let notification = match Notification::parse(&method, params) {
Ok(notification) => notification, Ok(notification) => notification,
Err(helix_lsp::Error::Unhandled) => {
info!("Ignoring Unhandled notification from Language Server");
return;
}
Err(err) => { Err(err) => {
log::error!( error!(
"received malformed notification from Language Server: {}", "Ignoring unknown notification from Language Server: {}",
err err
); );
return; return;