3102: Better error messages while deserializing r=matklad a=matklad



Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
bors[bot] 2020-02-11 08:47:36 +00:00 committed by GitHub
commit 6ac871b1df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 17 additions and 11 deletions

View File

@ -31,6 +31,8 @@ macro_rules! print {
mod world; mod world;
mod diagnostics; mod diagnostics;
use serde::de::DeserializeOwned;
pub type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>; pub type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;
pub use crate::{ pub use crate::{
caps::server_capabilities, caps::server_capabilities,
@ -38,3 +40,9 @@ macro_rules! print {
main_loop::LspError, main_loop::LspError,
main_loop::{main_loop, show_message}, main_loop::{main_loop, show_message},
}; };
pub fn from_json<T: DeserializeOwned>(what: &'static str, json: serde_json::Value) -> Result<T> {
let res = T::deserialize(&json)
.map_err(|e| format!("Failed to deserialize {}: {}; {}", what, e, json))?;
Ok(res)
}

View File

@ -1,7 +1,7 @@
//! `ra_lsp_server` binary //! `ra_lsp_server` binary
use lsp_server::Connection; use lsp_server::Connection;
use ra_lsp_server::{show_message, Result, ServerConfig}; use ra_lsp_server::{from_json, show_message, Result, ServerConfig};
use ra_prof; use ra_prof;
fn main() -> Result<()> { fn main() -> Result<()> {
@ -45,7 +45,8 @@ fn run_server() -> Result<()> {
let server_capabilities = serde_json::to_value(ra_lsp_server::server_capabilities()).unwrap(); let server_capabilities = serde_json::to_value(ra_lsp_server::server_capabilities()).unwrap();
let initialize_params = connection.initialize(server_capabilities)?; let initialize_params = connection.initialize(server_capabilities)?;
let initialize_params: lsp_types::InitializeParams = serde_json::from_value(initialize_params)?; let initialize_params =
from_json::<lsp_types::InitializeParams>("InitializeParams", initialize_params)?;
if let Some(client_info) = initialize_params.client_info { if let Some(client_info) = initialize_params.client_info {
log::info!("Client '{}' {}", client_info.name, client_info.version.unwrap_or_default()); log::info!("Client '{}' {}", client_info.name, client_info.version.unwrap_or_default());
@ -62,17 +63,13 @@ fn run_server() -> Result<()> {
.filter(|workspaces| !workspaces.is_empty()) .filter(|workspaces| !workspaces.is_empty())
.unwrap_or_else(|| vec![root]); .unwrap_or_else(|| vec![root]);
let server_config: ServerConfig = initialize_params let server_config = initialize_params
.initialization_options .initialization_options
.and_then(|v| { .and_then(|v| {
serde_json::from_value(v) from_json::<ServerConfig>("config", v)
.map_err(|e| { .map_err(|e| {
log::error!("failed to deserialize config: {}", e); log::error!("{}", e);
show_message( show_message(lsp_types::MessageType::Error, e.to_string(), &connection.sender);
lsp_types::MessageType::Error,
format!("failed to deserialize config: {}", e),
&connection.sender,
);
}) })
.ok() .ok()
}) })

View File

@ -35,6 +35,7 @@
TryConvWithToVec, TryConvWithToVec,
}, },
diagnostics::DiagnosticTask, diagnostics::DiagnosticTask,
from_json,
req::{self, Decoration, InlayHint, InlayHintsParams, InlayKind}, req::{self, Decoration, InlayHint, InlayHintsParams, InlayKind},
world::WorldSnapshot, world::WorldSnapshot,
LspError, Result, LspError, Result,
@ -811,7 +812,7 @@ enum CodeLensResolveData {
pub fn handle_code_lens_resolve(world: WorldSnapshot, code_lens: CodeLens) -> Result<CodeLens> { pub fn handle_code_lens_resolve(world: WorldSnapshot, code_lens: CodeLens) -> Result<CodeLens> {
let _p = profile("handle_code_lens_resolve"); let _p = profile("handle_code_lens_resolve");
let data = code_lens.data.unwrap(); let data = code_lens.data.unwrap();
let resolve = serde_json::from_value(data)?; let resolve = from_json::<Option<CodeLensResolveData>>("CodeLensResolveData", data)?;
match resolve { match resolve {
Some(CodeLensResolveData::Impls(lens_params)) => { Some(CodeLensResolveData::Impls(lens_params)) => {
let locations: Vec<Location> = let locations: Vec<Location> =