Add LspError to explicity return errors from LSP handlers

Fixes #145
This commit is contained in:
Jeremy A. Kolb 2018-10-22 13:49:27 -04:00
parent 5a64b9a811
commit 6453b29cb5
5 changed files with 25 additions and 4 deletions

1
Cargo.lock generated
View file

@ -654,6 +654,7 @@ dependencies = [
"crossbeam-channel 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-channel 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"drop_bomb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "drop_bomb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"failure_derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"flexi_logger 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", "flexi_logger 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
"gen_lsp_server 0.1.0", "gen_lsp_server 0.1.0",
"im 12.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "im 12.2.0 (registry+https://github.com/rust-lang/crates.io-index)",

View file

@ -8,6 +8,7 @@ authors = ["Aleksey Kladov <aleksey.kladov@gmail.com>"]
rayon = "1.0.2" rayon = "1.0.2"
relative-path = "0.3.7" relative-path = "0.3.7"
failure = "0.1.2" failure = "0.1.2"
failure_derive = "0.1.2"
serde_json = "1.0.24" serde_json = "1.0.24"
serde = "1.0.71" serde = "1.0.71"
serde_derive = "1.0.71" serde_derive = "1.0.71"

View file

@ -12,6 +12,8 @@ extern crate rayon;
extern crate log; extern crate log;
extern crate cargo_metadata; extern crate cargo_metadata;
extern crate drop_bomb; extern crate drop_bomb;
#[macro_use]
extern crate failure_derive;
extern crate im; extern crate im;
extern crate relative_path; extern crate relative_path;
extern crate rustc_hash; extern crate rustc_hash;
@ -34,4 +36,4 @@ pub mod thread_watcher;
mod vfs; mod vfs;
pub type Result<T> = ::std::result::Result<T, ::failure::Error>; pub type Result<T> = ::std::result::Result<T, ::failure::Error>;
pub use crate::{caps::server_capabilities, main_loop::main_loop}; pub use crate::{caps::server_capabilities, main_loop::main_loop, main_loop::LspError};

View file

@ -7,6 +7,7 @@ use languageserver_types::{
InsertTextFormat, Location, Position, SymbolInformation, TextDocumentIdentifier, TextEdit, InsertTextFormat, Location, Position, SymbolInformation, TextDocumentIdentifier, TextEdit,
RenameParams, WorkspaceEdit, PrepareRenameResponse RenameParams, WorkspaceEdit, PrepareRenameResponse
}; };
use gen_lsp_server::ErrorCode;
use ra_analysis::{FileId, FoldKind, Query, RunnableKind}; use ra_analysis::{FileId, FoldKind, Query, RunnableKind};
use ra_syntax::text_utils::contains_offset_nonstrict; use ra_syntax::text_utils::contains_offset_nonstrict;
use serde_json::to_value; use serde_json::to_value;
@ -16,7 +17,7 @@ use crate::{
project_model::TargetKind, project_model::TargetKind,
req::{self, Decoration}, req::{self, Decoration},
server_world::ServerWorld, server_world::ServerWorld,
Result, Result, LspError
}; };
pub fn handle_syntax_tree( pub fn handle_syntax_tree(
@ -476,7 +477,7 @@ pub fn handle_rename(
let offset = params.position.conv_with(&line_index); let offset = params.position.conv_with(&line_index);
if params.new_name.is_empty() { if params.new_name.is_empty() {
return Ok(None); return Err(LspError::new(ErrorCode::InvalidParams as i32, "New Name cannot be empty".into()).into());
} }
let refs = world.analysis().find_all_refs(file_id, offset)?; let refs = world.analysis().find_all_refs(file_id, offset)?;

View file

@ -23,6 +23,19 @@ use crate::{
Result, Result,
}; };
#[derive(Debug, Fail)]
#[fail(display = "Language Server request failed with {}. ({})", code, message)]
pub struct LspError {
pub code: i32,
pub message: String,
}
impl LspError {
pub fn new(code: i32, message: String) -> LspError {
LspError {code, message}
}
}
#[derive(Debug)] #[derive(Debug)]
enum Task { enum Task {
Respond(RawResponse), Respond(RawResponse),
@ -361,7 +374,10 @@ impl<'a> PoolDispatcher<'a> {
let resp = match f(world, params) { let resp = match f(world, params) {
Ok(resp) => RawResponse::ok::<R>(id, &resp), Ok(resp) => RawResponse::ok::<R>(id, &resp),
Err(e) => { Err(e) => {
RawResponse::err(id, ErrorCode::InternalError as i32, e.to_string()) match e.downcast::<LspError>() {
Ok(lsp_error) => RawResponse::err(id, lsp_error.code, lsp_error.message),
Err(e) => RawResponse::err(id, ErrorCode::InternalError as i32, e.to_string())
}
} }
}; };
let task = Task::Respond(resp); let task = Task::Respond(resp);