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.
pull/5465/merge
Michael Davis 2 years ago committed by GitHub
parent 563ac1a3cb
commit 170593161c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

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

Loading…
Cancel
Save