diff options
-rw-r--r-- | crates/ra_cargo_watch/Cargo.toml | 1 | ||||
-rw-r--r-- | crates/ra_cargo_watch/src/lib.rs | 30 |
2 files changed, 26 insertions, 5 deletions
diff --git a/crates/ra_cargo_watch/Cargo.toml b/crates/ra_cargo_watch/Cargo.toml index 49e06e0d3..dd814fc9d 100644 --- a/crates/ra_cargo_watch/Cargo.toml +++ b/crates/ra_cargo_watch/Cargo.toml | |||
@@ -11,6 +11,7 @@ log = "0.4.3" | |||
11 | cargo_metadata = "0.9.1" | 11 | cargo_metadata = "0.9.1" |
12 | jod-thread = "0.1.0" | 12 | jod-thread = "0.1.0" |
13 | parking_lot = "0.10.0" | 13 | parking_lot = "0.10.0" |
14 | serde_json = "1.0.45" | ||
14 | 15 | ||
15 | [dev-dependencies] | 16 | [dev-dependencies] |
16 | insta = "0.13.0" | 17 | insta = "0.13.0" |
diff --git a/crates/ra_cargo_watch/src/lib.rs b/crates/ra_cargo_watch/src/lib.rs index 9af9c347d..ea7ddc86b 100644 --- a/crates/ra_cargo_watch/src/lib.rs +++ b/crates/ra_cargo_watch/src/lib.rs | |||
@@ -9,7 +9,7 @@ use lsp_types::{ | |||
9 | }; | 9 | }; |
10 | use std::{ | 10 | use std::{ |
11 | collections::HashMap, | 11 | collections::HashMap, |
12 | io::BufReader, | 12 | io::{BufRead, BufReader}, |
13 | path::PathBuf, | 13 | path::PathBuf, |
14 | process::{Command, Stdio}, | 14 | process::{Command, Stdio}, |
15 | sync::Arc, | 15 | sync::Arc, |
@@ -350,13 +350,33 @@ impl WatchThread { | |||
350 | // which will break out of the loop, and continue the shutdown | 350 | // which will break out of the loop, and continue the shutdown |
351 | let _ = message_send.send(CheckEvent::Begin); | 351 | let _ = message_send.send(CheckEvent::Begin); |
352 | 352 | ||
353 | for message in | 353 | // We manually read a line at a time, instead of using serde's |
354 | cargo_metadata::parse_messages(BufReader::new(command.stdout.take().unwrap())) | 354 | // stream deserializers, because the deserializer cannot recover |
355 | { | 355 | // from an error, resulting in it getting stuck, because we try to |
356 | // be resillient against failures. | ||
357 | // | ||
358 | // Because cargo only outputs one JSON object per line, we can | ||
359 | // simply skip a line if it doesn't parse, which just ignores any | ||
360 | // erroneus output. | ||
361 | let stdout = BufReader::new(command.stdout.take().unwrap()); | ||
362 | for line in stdout.lines() { | ||
363 | let line = match line { | ||
364 | Ok(line) => line, | ||
365 | Err(err) => { | ||
366 | log::error!("Couldn't read line from cargo: {}", err); | ||
367 | continue; | ||
368 | } | ||
369 | }; | ||
370 | |||
371 | let message = serde_json::from_str::<cargo_metadata::Message>(&line); | ||
356 | let message = match message { | 372 | let message = match message { |
357 | Ok(message) => message, | 373 | Ok(message) => message, |
358 | Err(err) => { | 374 | Err(err) => { |
359 | log::error!("Invalid json from cargo check, ignoring: {}", err); | 375 | log::error!( |
376 | "Invalid json from cargo check, ignoring ({}): {:?} ", | ||
377 | err, | ||
378 | line | ||
379 | ); | ||
360 | continue; | 380 | continue; |
361 | } | 381 | } |
362 | }; | 382 | }; |