aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Bratschi-Kaye <[email protected]>2020-02-13 10:10:50 +0000
committerGitHub <[email protected]>2020-02-13 10:10:50 +0000
commit6f2cab1368dafc5663bb591a45062280a94a4ef9 (patch)
treeec226a181f8603e9f3e173dbdb33fdc2e96ae40c
parent39abac8c91321d724fb34ffc1a03a54946703dc2 (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.lock1
-rw-r--r--crates/ra_project_model/Cargo.toml2
-rw-r--r--crates/ra_project_model/src/cargo_workspace.rs11
-rw-r--r--crates/ra_project_model/src/lib.rs51
-rw-r--r--crates/ra_project_model/src/sysroot.rs14
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 = [
1247name = "ra_project_model" 1247name = "ra_project_model"
1248version = "0.1.0" 1248version = "0.1.0"
1249dependencies = [ 1249dependencies = [
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
20serde = { version = "1.0.89", features = ["derive"] } 20serde = { version = "1.0.89", features = ["derive"] }
21serde_json = "1.0.39" 21serde_json = "1.0.39"
22
23anyhow = "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
3use std::path::{Path, PathBuf}; 3use std::path::{Path, PathBuf};
4 4
5use anyhow::{Context, Result};
5use cargo_metadata::{CargoOpt, MetadataCommand}; 6use cargo_metadata::{CargoOpt, MetadataCommand};
6use ra_arena::{impl_arena_id, Arena, RawId}; 7use ra_arena::{impl_arena_id, Arena, RawId};
7use ra_db::Edition; 8use ra_db::Edition;
8use rustc_hash::FxHashMap; 9use rustc_hash::FxHashMap;
9use serde::Deserialize; 10use serde::Deserialize;
10 11
11use 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
15use anyhow::{bail, Context, Result};
15use ra_cfg::CfgOptions; 16use ra_cfg::CfgOptions;
16use ra_db::{CrateGraph, CrateId, CrateName, Edition, Env, FileId}; 17use ra_db::{CrateGraph, CrateId, CrateName, Edition, Env, FileId};
17use rustc_hash::FxHashMap; 18use rustc_hash::FxHashMap;
@@ -23,8 +24,6 @@ pub use crate::{
23 sysroot::Sysroot, 24 sysroot::Sysroot,
24}; 25};
25 26
26pub 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)]
29pub struct CargoTomlNotFoundError(pub PathBuf); 28pub 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
3use anyhow::{anyhow, bail, Context, Result};
3use std::{ 4use std::{
4 env, 5 env,
5 path::{Path, PathBuf}, 6 path::{Path, PathBuf},
@@ -8,8 +9,6 @@ use std::{
8 9
9use ra_arena::{impl_arena_id, Arena, RawId}; 10use ra_arena::{impl_arena_id, Arena, RawId};
10 11
11use crate::Result;
12
13#[derive(Default, Debug, Clone)] 12#[derive(Default, Debug, Clone)]
14pub struct Sysroot { 13pub 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());