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,35 +463,57 @@ 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) {
let response = f(params, cx.clone()); Ok(params) => {
cx.foreground() let response = f(params, cx.clone());
.spawn({ cx.foreground()
let outbound_tx = outbound_tx.clone(); .spawn({
async move { let outbound_tx = outbound_tx.clone();
let response = match response.await { async move {
Ok(result) => Response { let response = match response.await {
jsonrpc: JSON_RPC_VERSION, Ok(result) => Response {
id, jsonrpc: JSON_RPC_VERSION,
result: Some(result), id,
error: None, result: Some(result),
}, error: None,
Err(error) => Response { },
jsonrpc: JSON_RPC_VERSION, Err(error) => Response {
id, jsonrpc: JSON_RPC_VERSION,
result: None, id,
error: Some(Error { result: None,
message: error.to_string(), error: Some(Error {
}), message: error.to_string(),
}, }),
}; },
if let Some(response) = serde_json::to_vec(&response).log_err() };
{ if let Some(response) =
outbound_tx.try_send(response).ok(); serde_json::to_vec(&response).log_err()
{
outbound_tx.try_send(response).ok();
}
} }
} })
}) .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();
}
}
} }
} }
}), }),