Skip to content

Commit 8541acb

Browse files
committed
Fix error reporting when language server quit unexpectedly.
1 parent a51c84a commit 8541acb

File tree

4 files changed

+63
-44
lines changed

4 files changed

+63
-44
lines changed

src/languageclient.rs

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2360,14 +2360,24 @@ impl State {
23602360
Ok(())
23612361
})?;
23622362

2363-
let languageId_clone = languageId.clone();
23642363
let thread_name = format!("reader-{}", languageId);
23652364
let tx = self.tx.clone();
23662365
std::thread::Builder::new()
23672366
.name(thread_name.clone())
23682367
.spawn(move || {
2369-
if let Err(err) = loop_reader(reader, &Some(languageId_clone), &tx) {
2370-
error!("{} reader loop exited: {:?}", thread_name, err);
2368+
if let Err(err) = loop_reader(reader, &Some(languageId.clone()), &tx) {
2369+
let _ = tx.send(Message::Notification(
2370+
Some(languageId.clone()),
2371+
rpc::Notification {
2372+
jsonrpc: None,
2373+
method: NOTIFICATION__ServerExited.into(),
2374+
params: json!({
2375+
"languageId": languageId,
2376+
"message": format!("{}", err),
2377+
}).to_params()
2378+
.unwrap_or_default(),
2379+
},
2380+
));
23712381
}
23722382
})?;
23732383

@@ -2385,4 +2395,21 @@ impl State {
23852395
self.call::<_, u8>(None, "s:ExecuteAutocmd", "LanguageClientStarted")?;
23862396
Ok(Value::Null)
23872397
}
2398+
2399+
pub fn languageClient_serverExited(&mut self, params: &Option<Params>) -> Result<()> {
2400+
let (languageId, message): (String, String) = self.gather_args(
2401+
[VimVar::LanguageId.to_key().as_str(), "message"].as_ref(),
2402+
params,
2403+
)?;
2404+
2405+
if self.writers.contains_key(&languageId) {
2406+
let _ = self.cleanup(languageId.as_str());
2407+
let _ = self.echoerr(format!(
2408+
"Language server {} exited unexpectedly: {}",
2409+
languageId, message
2410+
));
2411+
}
2412+
2413+
Ok(())
2414+
}
23882415
}

src/rpchandler.rs

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -80,20 +80,21 @@ impl State {
8080
REQUEST__OmniComplete => self.languageClient_omniComplete(&method_call.params),
8181

8282
_ => {
83-
if languageId.is_none() {
84-
// Request from vim, pass through.
85-
let (languageId,): (String,) =
83+
let languageId_target = if languageId.is_some() {
84+
// Message from language server. Proxy to vim.
85+
None
86+
} else {
87+
// Message from vim. Proxy to language server.
88+
let (languageId_target,): (String,) =
8689
self.gather_args(&[VimVar::LanguageId], &method_call.params)?;
90+
Some(languageId_target)
91+
};
8792

88-
self.call(
89-
Some(languageId.as_str()),
90-
&method_call.method,
91-
&method_call.params,
92-
)
93-
} else {
94-
// Request from language servers.
95-
Err(format_err!("No handler found for: {:?}", method_call))
96-
}
93+
self.call(
94+
languageId_target.as_deref(),
95+
&method_call.method,
96+
&method_call.params,
97+
)
9798
}
9899
}
99100
}
@@ -166,22 +167,24 @@ impl State {
166167
}
167168
NOTIFICATION__WindowProgress => self.window_progress(&notification.params)?,
168169
NOTIFICATION__CqueryProgress => self.cquery_handleProgress(&notification.params)?,
170+
NOTIFICATION__ServerExited => self.languageClient_serverExited(&notification.params)?,
169171

170172
_ => {
171-
if languageId.is_none() {
172-
// Notification from vim, pass through.
173-
let (languageId,): (String,) =
173+
let languageId_target = if languageId.is_some() {
174+
// Message from language server. Proxy to vim.
175+
None
176+
} else {
177+
// Message from vim. Proxy to language server.
178+
let (languageId_target,): (String,) =
174179
self.gather_args(&[VimVar::LanguageId], &notification.params)?;
180+
Some(languageId_target)
181+
};
175182

176-
self.notify(
177-
Some(languageId.as_str()),
178-
&notification.method,
179-
&notification.params,
180-
)?;
181-
} else {
182-
// Notification from language servers.
183-
warn!("No handler found for: {:?}", notification);
184-
}
183+
self.notify(
184+
languageId_target.as_deref(),
185+
&notification.method,
186+
&notification.params,
187+
)?;
185188
}
186189
};
187190

src/types.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ pub const NOTIFICATION__HandleBufDelete: &str = "languageClient/handleBufDelete"
2525
pub const NOTIFICATION__HandleCursorMoved: &str = "languageClient/handleCursorMoved";
2626
pub const NOTIFICATION__FZFSinkLocation: &str = "LanguageClient_FZFSinkLocation";
2727
pub const NOTIFICATION__FZFSinkCommand: &str = "LanguageClient_FZFSinkCommand";
28+
pub const NOTIFICATION__ServerExited: &str = "$languageClient/serverExisted";
2829

2930
// Extensions by language servers.
3031
pub const REQUEST__RustImplementations: &str = "rustDocument/implementations";

src/vim.rs

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -312,24 +312,12 @@ pub fn loop_reader<T: BufRead>(
312312
if line.is_empty() {
313313
count_empty_lines += 1;
314314
if count_empty_lines > 5 {
315-
// TODO
316-
// if let Err(err) = self.cleanup(&languageId) {
317-
// error!("Error when cleanup: {:?}", err);
318-
// }
319-
320-
let mut message =
321-
format!("Language server ({}) exited unexpectedly!", languageId);
322-
match get_log_server() {
323-
Ok(log_server) => {
324-
message += "\n\nlanguage server stderr:\n";
325-
message += &log_server;
326-
}
327-
Err(err) => error!("Error when get_log_server: {:?}", err),
315+
let mut message = "".to_string();
316+
if let Ok(log_server) = get_log_server() {
317+
message += "\n\nlanguage server stderr:\n";
318+
message += &log_server;
328319
}
329-
// TODO
330-
// if let Err(err) = self.echoerr(&message) {
331-
// error!("Error in echoerr: {:?}", err);
332-
// };
320+
333321
bail!("{}", message);
334322
}
335323

0 commit comments

Comments
 (0)