mirror of https://github.com/helix-editor/helix
Don't panic on LSP parsing errors
This made sense initially when the implementation was still new (so we got user reports more frequently), but a parsing error now generally signifies a language server isn't properly implementing the spec.pull/2461/head
parent
8b1a03a178
commit
7ae6cad52e
|
@ -40,6 +40,8 @@ pub enum Error {
|
||||||
StreamClosed,
|
StreamClosed,
|
||||||
#[error("LSP not defined")]
|
#[error("LSP not defined")]
|
||||||
LspNotDefined,
|
LspNotDefined,
|
||||||
|
#[error("Unhandled")]
|
||||||
|
Unhandled,
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Other(#[from] anyhow::Error),
|
Other(#[from] anyhow::Error),
|
||||||
}
|
}
|
||||||
|
@ -226,34 +228,27 @@ pub enum MethodCall {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MethodCall {
|
impl MethodCall {
|
||||||
pub fn parse(method: &str, params: jsonrpc::Params) -> Option<MethodCall> {
|
pub fn parse(method: &str, params: jsonrpc::Params) -> Result<MethodCall> {
|
||||||
use lsp::request::Request;
|
use lsp::request::Request;
|
||||||
let request = match method {
|
let request = match method {
|
||||||
lsp::request::WorkDoneProgressCreate::METHOD => {
|
lsp::request::WorkDoneProgressCreate::METHOD => {
|
||||||
let params: lsp::WorkDoneProgressCreateParams = params
|
let params: lsp::WorkDoneProgressCreateParams = params.parse()?;
|
||||||
.parse()
|
|
||||||
.expect("Failed to parse WorkDoneCreate params");
|
|
||||||
Self::WorkDoneProgressCreate(params)
|
Self::WorkDoneProgressCreate(params)
|
||||||
}
|
}
|
||||||
lsp::request::ApplyWorkspaceEdit::METHOD => {
|
lsp::request::ApplyWorkspaceEdit::METHOD => {
|
||||||
let params: lsp::ApplyWorkspaceEditParams = params
|
let params: lsp::ApplyWorkspaceEditParams = params.parse()?;
|
||||||
.parse()
|
|
||||||
.expect("Failed to parse ApplyWorkspaceEdit params");
|
|
||||||
Self::ApplyWorkspaceEdit(params)
|
Self::ApplyWorkspaceEdit(params)
|
||||||
}
|
}
|
||||||
lsp::request::WorkspaceFoldersRequest::METHOD => Self::WorkspaceFolders,
|
lsp::request::WorkspaceFoldersRequest::METHOD => Self::WorkspaceFolders,
|
||||||
lsp::request::WorkspaceConfiguration::METHOD => {
|
lsp::request::WorkspaceConfiguration::METHOD => {
|
||||||
let params: lsp::ConfigurationParams = params
|
let params: lsp::ConfigurationParams = params.parse()?;
|
||||||
.parse()
|
|
||||||
.expect("Failed to parse WorkspaceConfiguration params");
|
|
||||||
Self::WorkspaceConfiguration(params)
|
Self::WorkspaceConfiguration(params)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
log::warn!("unhandled lsp request: {}", method);
|
return Err(Error::Unhandled);
|
||||||
return None;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Some(request)
|
Ok(request)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,48 +263,34 @@ pub enum Notification {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Notification {
|
impl Notification {
|
||||||
pub fn parse(method: &str, params: jsonrpc::Params) -> Option<Notification> {
|
pub fn parse(method: &str, params: jsonrpc::Params) -> Result<Notification> {
|
||||||
use lsp::notification::Notification as _;
|
use lsp::notification::Notification as _;
|
||||||
|
|
||||||
let notification = match method {
|
let notification = match method {
|
||||||
lsp::notification::Initialized::METHOD => Self::Initialized,
|
lsp::notification::Initialized::METHOD => Self::Initialized,
|
||||||
lsp::notification::PublishDiagnostics::METHOD => {
|
lsp::notification::PublishDiagnostics::METHOD => {
|
||||||
let params: lsp::PublishDiagnosticsParams = params
|
let params: lsp::PublishDiagnosticsParams = params.parse()?;
|
||||||
.parse()
|
|
||||||
.map_err(|err| {
|
|
||||||
log::error!(
|
|
||||||
"received malformed PublishDiagnostic from Language Server: {}",
|
|
||||||
err
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.ok()?;
|
|
||||||
|
|
||||||
// TODO: need to loop over diagnostics and distinguish them by URI
|
|
||||||
Self::PublishDiagnostics(params)
|
Self::PublishDiagnostics(params)
|
||||||
}
|
}
|
||||||
|
|
||||||
lsp::notification::ShowMessage::METHOD => {
|
lsp::notification::ShowMessage::METHOD => {
|
||||||
let params: lsp::ShowMessageParams = params.parse().ok()?;
|
let params: lsp::ShowMessageParams = params.parse()?;
|
||||||
|
|
||||||
Self::ShowMessage(params)
|
Self::ShowMessage(params)
|
||||||
}
|
}
|
||||||
lsp::notification::LogMessage::METHOD => {
|
lsp::notification::LogMessage::METHOD => {
|
||||||
let params: lsp::LogMessageParams = params.parse().ok()?;
|
let params: lsp::LogMessageParams = params.parse()?;
|
||||||
|
|
||||||
Self::LogMessage(params)
|
Self::LogMessage(params)
|
||||||
}
|
}
|
||||||
lsp::notification::Progress::METHOD => {
|
lsp::notification::Progress::METHOD => {
|
||||||
let params: lsp::ProgressParams = params.parse().ok()?;
|
let params: lsp::ProgressParams = params.parse()?;
|
||||||
|
|
||||||
Self::ProgressMessage(params)
|
Self::ProgressMessage(params)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
log::error!("unhandled LSP notification: {}", method);
|
return Err(Error::Unhandled);
|
||||||
return None;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Some(notification)
|
Ok(notification)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -399,8 +399,14 @@ impl Application {
|
||||||
match call {
|
match call {
|
||||||
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) {
|
||||||
Some(notification) => notification,
|
Ok(notification) => notification,
|
||||||
None => return,
|
Err(err) => {
|
||||||
|
log::error!(
|
||||||
|
"received malformed notification from Language Server: {}",
|
||||||
|
err
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
match notification {
|
match notification {
|
||||||
|
@ -613,9 +619,17 @@ impl Application {
|
||||||
method, params, id, ..
|
method, params, id, ..
|
||||||
}) => {
|
}) => {
|
||||||
let call = match MethodCall::parse(&method, params) {
|
let call = match MethodCall::parse(&method, params) {
|
||||||
Some(call) => call,
|
Ok(call) => call,
|
||||||
None => {
|
Err(helix_lsp::Error::Unhandled) => {
|
||||||
error!("Method not found {}", method);
|
error!("Language Server: Method not found {}", method);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
log::error!(
|
||||||
|
"received malformed method call from Language Server: {}: {}",
|
||||||
|
method,
|
||||||
|
err
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue