LSP: Send replies for malformed and unhandled RPC requests (#6058)

Previously we did not respond to malformed or unhandled LSP requests.
The JSONRPC spec says that all non-notification requests must have
responses:

> When a rpc call is made, the Server MUST reply with a Response,
> except for in the case of Notifications

(Note that Helix is the "Server" in this case. Also from the spec:
"The Server is defined as the origin of Response objects and the
handler of Request objects.")

So this change sends error replies for requests which can't be parsed
or handled. Request IDs are also now added to the log messages for
unhandled requests.
This commit is contained in:
Michael Davis 2023-03-07 19:50:57 -06:00 committed by GitHub
parent 563ac1a3cb
commit 170593161c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -928,24 +928,32 @@ pub async fn handle_language_server_message(
Call::MethodCall(helix_lsp::jsonrpc::MethodCall {
method, params, id, ..
}) => {
let call = match MethodCall::parse(&method, params) {
Ok(call) => call,
let reply = match MethodCall::parse(&method, params) {
Err(helix_lsp::Error::Unhandled) => {
error!("Language Server: Method not found {}", method);
return;
error!(
"Language Server: Method {} not found in request {}",
method, id
);
Err(helix_lsp::jsonrpc::Error {
code: helix_lsp::jsonrpc::ErrorCode::MethodNotFound,
message: format!("Method not found: {}", method),
data: None,
})
}
Err(err) => {
log::error!(
"received malformed method call from Language Server: {}: {}",
"Language Server: Received malformed method call {} in request {}: {}",
method,
id,
err
);
return;
Err(helix_lsp::jsonrpc::Error {
code: helix_lsp::jsonrpc::ErrorCode::ParseError,
message: format!("Malformed method call: {}", method),
data: None,
})
}
};
let reply = match call {
MethodCall::WorkDoneProgressCreate(params) => {
Ok(MethodCall::WorkDoneProgressCreate(params)) => {
self.lsp_progress.create(server_id, params.token);
let editor_view = self
@ -959,7 +967,7 @@ pub async fn handle_language_server_message(
Ok(serde_json::Value::Null)
}
MethodCall::ApplyWorkspaceEdit(params) => {
Ok(MethodCall::ApplyWorkspaceEdit(params)) => {
apply_workspace_edit(
&mut self.editor,
helix_lsp::OffsetEncoding::Utf8,
@ -972,13 +980,13 @@ pub async fn handle_language_server_message(
failed_change: None,
}))
}
MethodCall::WorkspaceFolders => {
Ok(MethodCall::WorkspaceFolders) => {
let language_server =
self.editor.language_servers.get_by_id(server_id).unwrap();
Ok(json!(language_server.workspace_folders()))
}
MethodCall::WorkspaceConfiguration(params) => {
Ok(MethodCall::WorkspaceConfiguration(params)) => {
let result: Vec<_> = params
.items
.iter()