diff options
author | Adam Bratschi-Kaye <[email protected]> | 2020-02-13 10:10:50 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2020-02-13 10:10:50 +0000 |
commit | 6f2cab1368dafc5663bb591a45062280a94a4ef9 (patch) | |
tree | ec226a181f8603e9f3e173dbdb33fdc2e96ae40c | |
parent | 39abac8c91321d724fb34ffc1a03a54946703dc2 (diff) |
Add error context to failures in `ra_project_model` using `anyhow` crate (#3119)
Add error context to failures in ra_project_model using anyhow crate
-rw-r--r-- | Cargo.lock | 1 | ||||
-rw-r--r-- | crates/ra_project_model/Cargo.toml | 2 | ||||
-rw-r--r-- | crates/ra_project_model/src/cargo_workspace.rs | 11 | ||||
-rw-r--r-- | crates/ra_project_model/src/lib.rs | 51 | ||||
-rw-r--r-- | crates/ra_project_model/src/sysroot.rs | 14 |
5 files changed, 59 insertions, 20 deletions
diff --git a/Cargo.lock b/Cargo.lock index 45804c087..f1651edaa 100644 --- a/Cargo.lock +++ b/Cargo.lock | |||
@@ -1247,6 +1247,7 @@ dependencies = [ | |||
1247 | name = "ra_project_model" | 1247 | name = "ra_project_model" |
1248 | version = "0.1.0" | 1248 | version = "0.1.0" |
1249 | dependencies = [ | 1249 | dependencies = [ |
1250 | "anyhow", | ||
1250 | "cargo_metadata", | 1251 | "cargo_metadata", |
1251 | "log", | 1252 | "log", |
1252 | "ra_arena", | 1253 | "ra_arena", |
diff --git a/crates/ra_project_model/Cargo.toml b/crates/ra_project_model/Cargo.toml index 69edc3c66..653d5bd14 100644 --- a/crates/ra_project_model/Cargo.toml +++ b/crates/ra_project_model/Cargo.toml | |||
@@ -19,3 +19,5 @@ ra_cfg = { path = "../ra_cfg" } | |||
19 | 19 | ||
20 | serde = { version = "1.0.89", features = ["derive"] } | 20 | serde = { version = "1.0.89", features = ["derive"] } |
21 | serde_json = "1.0.39" | 21 | serde_json = "1.0.39" |
22 | |||
23 | anyhow = "1.0.26" | ||
diff --git a/crates/ra_project_model/src/cargo_workspace.rs b/crates/ra_project_model/src/cargo_workspace.rs index 60cb8c1eb..22d226a74 100644 --- a/crates/ra_project_model/src/cargo_workspace.rs +++ b/crates/ra_project_model/src/cargo_workspace.rs | |||
@@ -2,14 +2,13 @@ | |||
2 | 2 | ||
3 | use std::path::{Path, PathBuf}; | 3 | use std::path::{Path, PathBuf}; |
4 | 4 | ||
5 | use anyhow::{Context, Result}; | ||
5 | use cargo_metadata::{CargoOpt, MetadataCommand}; | 6 | use cargo_metadata::{CargoOpt, MetadataCommand}; |
6 | use ra_arena::{impl_arena_id, Arena, RawId}; | 7 | use ra_arena::{impl_arena_id, Arena, RawId}; |
7 | use ra_db::Edition; | 8 | use ra_db::Edition; |
8 | use rustc_hash::FxHashMap; | 9 | use rustc_hash::FxHashMap; |
9 | use serde::Deserialize; | 10 | use serde::Deserialize; |
10 | 11 | ||
11 | use crate::Result; | ||
12 | |||
13 | /// `CargoWorkspace` represents the logical structure of, well, a Cargo | 12 | /// `CargoWorkspace` represents the logical structure of, well, a Cargo |
14 | /// workspace. It pretty closely mirrors `cargo metadata` output. | 13 | /// workspace. It pretty closely mirrors `cargo metadata` output. |
15 | /// | 14 | /// |
@@ -171,7 +170,9 @@ impl CargoWorkspace { | |||
171 | if let Some(parent) = cargo_toml.parent() { | 170 | if let Some(parent) = cargo_toml.parent() { |
172 | meta.current_dir(parent); | 171 | meta.current_dir(parent); |
173 | } | 172 | } |
174 | let meta = meta.exec().map_err(|e| format!("cargo metadata failed: {}", e))?; | 173 | let meta = meta.exec().with_context(|| { |
174 | format!("Failed to run `cargo metadata --manifest-path {}`", cargo_toml.display()) | ||
175 | })?; | ||
175 | let mut pkg_by_id = FxHashMap::default(); | 176 | let mut pkg_by_id = FxHashMap::default(); |
176 | let mut packages = Arena::default(); | 177 | let mut packages = Arena::default(); |
177 | let mut targets = Arena::default(); | 178 | let mut targets = Arena::default(); |
@@ -181,7 +182,9 @@ impl CargoWorkspace { | |||
181 | for meta_pkg in meta.packages { | 182 | for meta_pkg in meta.packages { |
182 | let cargo_metadata::Package { id, edition, name, manifest_path, .. } = meta_pkg; | 183 | let cargo_metadata::Package { id, edition, name, manifest_path, .. } = meta_pkg; |
183 | let is_member = ws_members.contains(&id); | 184 | let is_member = ws_members.contains(&id); |
184 | let edition = edition.parse::<Edition>()?; | 185 | let edition = edition |
186 | .parse::<Edition>() | ||
187 | .with_context(|| format!("Failed to parse edition {}", edition))?; | ||
185 | let pkg = packages.alloc(PackageData { | 188 | let pkg = packages.alloc(PackageData { |
186 | name, | 189 | name, |
187 | manifest: manifest_path, | 190 | manifest: manifest_path, |
diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs index bc1d15406..fef405b7f 100644 --- a/crates/ra_project_model/src/lib.rs +++ b/crates/ra_project_model/src/lib.rs | |||
@@ -12,6 +12,7 @@ use std::{ | |||
12 | process::Command, | 12 | process::Command, |
13 | }; | 13 | }; |
14 | 14 | ||
15 | use anyhow::{bail, Context, Result}; | ||
15 | use ra_cfg::CfgOptions; | 16 | use ra_cfg::CfgOptions; |
16 | use ra_db::{CrateGraph, CrateId, CrateName, Edition, Env, FileId}; | 17 | use ra_db::{CrateGraph, CrateId, CrateName, Edition, Env, FileId}; |
17 | use rustc_hash::FxHashMap; | 18 | use rustc_hash::FxHashMap; |
@@ -23,8 +24,6 @@ pub use crate::{ | |||
23 | sysroot::Sysroot, | 24 | sysroot::Sysroot, |
24 | }; | 25 | }; |
25 | 26 | ||
26 | pub type Result<T> = ::std::result::Result<T, Box<dyn Error + Send + Sync>>; | ||
27 | |||
28 | #[derive(Clone, PartialEq, Eq, Hash, Debug)] | 27 | #[derive(Clone, PartialEq, Eq, Hash, Debug)] |
29 | pub struct CargoTomlNotFoundError(pub PathBuf); | 28 | pub struct CargoTomlNotFoundError(pub PathBuf); |
30 | 29 | ||
@@ -81,15 +80,36 @@ impl ProjectWorkspace { | |||
81 | ) -> Result<ProjectWorkspace> { | 80 | ) -> Result<ProjectWorkspace> { |
82 | match find_rust_project_json(path) { | 81 | match find_rust_project_json(path) { |
83 | Some(json_path) => { | 82 | Some(json_path) => { |
84 | let file = File::open(json_path)?; | 83 | let file = File::open(&json_path) |
84 | .with_context(|| format!("Failed to open json file {}", json_path.display()))?; | ||
85 | let reader = BufReader::new(file); | 85 | let reader = BufReader::new(file); |
86 | Ok(ProjectWorkspace::Json { project: from_reader(reader)? }) | 86 | Ok(ProjectWorkspace::Json { |
87 | project: from_reader(reader).with_context(|| { | ||
88 | format!("Failed to deserialize json file {}", json_path.display()) | ||
89 | })?, | ||
90 | }) | ||
87 | } | 91 | } |
88 | None => { | 92 | None => { |
89 | let cargo_toml = find_cargo_toml(path)?; | 93 | let cargo_toml = find_cargo_toml(path).with_context(|| { |
90 | let cargo = CargoWorkspace::from_cargo_metadata(&cargo_toml, cargo_features)?; | 94 | format!("Failed to find Cargo.toml for path {}", path.display()) |
91 | let sysroot = | 95 | })?; |
92 | if with_sysroot { Sysroot::discover(&cargo_toml)? } else { Sysroot::default() }; | 96 | let cargo = CargoWorkspace::from_cargo_metadata(&cargo_toml, cargo_features) |
97 | .with_context(|| { | ||
98 | format!( | ||
99 | "Failed to read Cargo metadata from Cargo.toml file {}", | ||
100 | cargo_toml.display() | ||
101 | ) | ||
102 | })?; | ||
103 | let sysroot = if with_sysroot { | ||
104 | Sysroot::discover(&cargo_toml).with_context(|| { | ||
105 | format!( | ||
106 | "Failed to find sysroot for Cargo.toml file {}", | ||
107 | cargo_toml.display() | ||
108 | ) | ||
109 | })? | ||
110 | } else { | ||
111 | Sysroot::default() | ||
112 | }; | ||
93 | Ok(ProjectWorkspace::Cargo { cargo, sysroot }) | 113 | Ok(ProjectWorkspace::Cargo { cargo, sysroot }) |
94 | } | 114 | } |
95 | } | 115 | } |
@@ -403,11 +423,20 @@ pub fn get_rustc_cfg_options() -> CfgOptions { | |||
403 | } | 423 | } |
404 | } | 424 | } |
405 | 425 | ||
406 | match (|| -> Result<_> { | 426 | match (|| -> Result<String> { |
407 | // `cfg(test)` and `cfg(debug_assertion)` are handled outside, so we suppress them here. | 427 | // `cfg(test)` and `cfg(debug_assertion)` are handled outside, so we suppress them here. |
408 | let output = Command::new("rustc").args(&["--print", "cfg", "-O"]).output()?; | 428 | let output = Command::new("rustc") |
429 | .args(&["--print", "cfg", "-O"]) | ||
430 | .output() | ||
431 | .context("Failed to get output from rustc --print cfg -O")?; | ||
409 | if !output.status.success() { | 432 | if !output.status.success() { |
410 | Err("failed to get rustc cfgs")?; | 433 | bail!( |
434 | "rustc --print cfg -O exited with exit code ({})", | ||
435 | output | ||
436 | .status | ||
437 | .code() | ||
438 | .map_or(String::from("no exit code"), |code| format!("{}", code)) | ||
439 | ); | ||
411 | } | 440 | } |
412 | Ok(String::from_utf8(output.stdout)?) | 441 | Ok(String::from_utf8(output.stdout)?) |
413 | })() { | 442 | })() { |
diff --git a/crates/ra_project_model/src/sysroot.rs b/crates/ra_project_model/src/sysroot.rs index a23265fc0..7b9cc899c 100644 --- a/crates/ra_project_model/src/sysroot.rs +++ b/crates/ra_project_model/src/sysroot.rs | |||
@@ -1,5 +1,6 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use anyhow::{anyhow, bail, Context, Result}; | ||
3 | use std::{ | 4 | use std::{ |
4 | env, | 5 | env, |
5 | path::{Path, PathBuf}, | 6 | path::{Path, PathBuf}, |
@@ -8,8 +9,6 @@ use std::{ | |||
8 | 9 | ||
9 | use ra_arena::{impl_arena_id, Arena, RawId}; | 10 | use ra_arena::{impl_arena_id, Arena, RawId}; |
10 | 11 | ||
11 | use crate::Result; | ||
12 | |||
13 | #[derive(Default, Debug, Clone)] | 12 | #[derive(Default, Debug, Clone)] |
14 | pub struct Sysroot { | 13 | pub struct Sysroot { |
15 | crates: Arena<SysrootCrate, SysrootCrateData>, | 14 | crates: Arena<SysrootCrate, SysrootCrateData>, |
@@ -51,7 +50,7 @@ impl Sysroot { | |||
51 | let src = try_find_src_path(cargo_toml)?; | 50 | let src = try_find_src_path(cargo_toml)?; |
52 | 51 | ||
53 | if !src.exists() { | 52 | if !src.exists() { |
54 | Err(format!( | 53 | Err(anyhow!( |
55 | "can't load standard library from sysroot\n\ | 54 | "can't load standard library from sysroot\n\ |
56 | {}\n\ | 55 | {}\n\ |
57 | (discovered via `rustc --print sysroot`)\n\ | 56 | (discovered via `rustc --print sysroot`)\n\ |
@@ -100,9 +99,14 @@ fn try_find_src_path(cargo_toml: &Path) -> Result<PathBuf> { | |||
100 | .current_dir(cargo_toml.parent().unwrap()) | 99 | .current_dir(cargo_toml.parent().unwrap()) |
101 | .args(&["--print", "sysroot"]) | 100 | .args(&["--print", "sysroot"]) |
102 | .output() | 101 | .output() |
103 | .map_err(|e| format!("rustc --print sysroot failed: {}", e))?; | 102 | .context("rustc --print sysroot failed")?; |
104 | if !rustc_output.status.success() { | 103 | if !rustc_output.status.success() { |
105 | Err("failed to locate sysroot")?; | 104 | match rustc_output.status.code() { |
105 | Some(code) => { | ||
106 | bail!("failed to locate sysroot: rustc --print sysroot exited with code {}", code) | ||
107 | } | ||
108 | None => bail!("failed to locate sysroot: rustc --print sysroot terminated by signal"), | ||
109 | }; | ||
106 | } | 110 | } |
107 | let stdout = String::from_utf8(rustc_output.stdout)?; | 111 | let stdout = String::from_utf8(rustc_output.stdout)?; |
108 | let sysroot_path = Path::new(stdout.trim()); | 112 | let sysroot_path = Path::new(stdout.trim()); |