Always respond to language server, even when its requests are malformed

This was causing Pyright to get stuck waiting for a response when sending
us the `workspace/configuration` request. For some reason, after upgrading
to Pyright 1.1.293, `scopeUri` is being sent as an empty string sometimes,
which causes serde to error when trying to deserialize that request.

Co-Authored-By: Petros Amoiridis <petros@zed.dev>
This commit is contained in:
Antonio Scandurra 2023-02-09 15:30:10 +01:00
parent 767d2f9766
commit c3a88857f9

View file

@ -65,6 +65,7 @@ struct Request<'a, T> {
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
struct AnyResponse<'a> { struct AnyResponse<'a> {
jsonrpc: &'a str,
id: usize, id: usize,
#[serde(default)] #[serde(default)]
error: Option<Error>, error: Option<Error>,
@ -204,8 +205,9 @@ impl LanguageServer {
} else { } else {
on_unhandled_notification(msg); on_unhandled_notification(msg);
} }
} else if let Ok(AnyResponse { id, error, result }) = } else if let Ok(AnyResponse {
serde_json::from_slice(&buffer) id, error, result, ..
}) = serde_json::from_slice(&buffer)
{ {
if let Some(handler) = response_handlers if let Some(handler) = response_handlers
.lock() .lock()
@ -461,7 +463,8 @@ impl LanguageServer {
method, method,
Box::new(move |id, params, cx| { Box::new(move |id, params, cx| {
if let Some(id) = id { if let Some(id) = id {
if let Some(params) = serde_json::from_str(params).log_err() { match serde_json::from_str(params) {
Ok(params) => {
let response = f(params, cx.clone()); let response = f(params, cx.clone());
cx.foreground() cx.foreground()
.spawn({ .spawn({
@ -483,7 +486,8 @@ impl LanguageServer {
}), }),
}, },
}; };
if let Some(response) = serde_json::to_vec(&response).log_err() if let Some(response) =
serde_json::to_vec(&response).log_err()
{ {
outbound_tx.try_send(response).ok(); outbound_tx.try_send(response).ok();
} }
@ -491,6 +495,26 @@ impl LanguageServer {
}) })
.detach(); .detach();
} }
Err(error) => {
log::error!(
"error deserializing {} request: {:?}, message: {:?}",
method,
error,
params
);
let response = AnyResponse {
jsonrpc: JSON_RPC_VERSION,
id,
result: None,
error: Some(Error {
message: error.to_string(),
}),
};
if let Some(response) = serde_json::to_vec(&response).log_err() {
outbound_tx.try_send(response).ok();
}
}
}
} }
}), }),
); );