Skip to content

Commit 6f2cab1

Browse files
authored
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
1 parent 39abac8 commit 6f2cab1

File tree

5 files changed

+59
-20
lines changed

5 files changed

+59
-20
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/ra_project_model/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,5 @@ ra_cfg = { path = "../ra_cfg" }
1919

2020
serde = { version = "1.0.89", features = ["derive"] }
2121
serde_json = "1.0.39"
22+
23+
anyhow = "1.0.26"

crates/ra_project_model/src/cargo_workspace.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,13 @@
22
33
use std::path::{Path, PathBuf};
44

5+
use anyhow::{Context, Result};
56
use cargo_metadata::{CargoOpt, MetadataCommand};
67
use ra_arena::{impl_arena_id, Arena, RawId};
78
use ra_db::Edition;
89
use rustc_hash::FxHashMap;
910
use serde::Deserialize;
1011

11-
use crate::Result;
12-
1312
/// `CargoWorkspace` represents the logical structure of, well, a Cargo
1413
/// workspace. It pretty closely mirrors `cargo metadata` output.
1514
///
@@ -171,7 +170,9 @@ impl CargoWorkspace {
171170
if let Some(parent) = cargo_toml.parent() {
172171
meta.current_dir(parent);
173172
}
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+
})?;
175176
let mut pkg_by_id = FxHashMap::default();
176177
let mut packages = Arena::default();
177178
let mut targets = Arena::default();
@@ -181,7 +182,9 @@ impl CargoWorkspace {
181182
for meta_pkg in meta.packages {
182183
let cargo_metadata::Package { id, edition, name, manifest_path, .. } = meta_pkg;
183184
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))?;
185188
let pkg = packages.alloc(PackageData {
186189
name,
187190
manifest: manifest_path,

crates/ra_project_model/src/lib.rs

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use std::{
1212
process::Command,
1313
};
1414

15+
use anyhow::{bail, Context, Result};
1516
use ra_cfg::CfgOptions;
1617
use ra_db::{CrateGraph, CrateId, CrateName, Edition, Env, FileId};
1718
use rustc_hash::FxHashMap;
@@ -23,8 +24,6 @@ pub use crate::{
2324
sysroot::Sysroot,
2425
};
2526

26-
pub type Result<T> = ::std::result::Result<T, Box<dyn Error + Send + Sync>>;
27-
2827
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
2928
pub struct CargoTomlNotFoundError(pub PathBuf);
3029

@@ -81,15 +80,36 @@ impl ProjectWorkspace {
8180
) -> Result<ProjectWorkspace> {
8281
match find_rust_project_json(path) {
8382
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()))?;
8585
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+
})
8791
}
8892
None => {
89-
let cargo_toml = find_cargo_toml(path)?;
90-
let cargo = CargoWorkspace::from_cargo_metadata(&cargo_toml, cargo_features)?;
91-
let sysroot =
92-
if with_sysroot { Sysroot::discover(&cargo_toml)? } else { Sysroot::default() };
93+
let cargo_toml = find_cargo_toml(path).with_context(|| {
94+
format!("Failed to find Cargo.toml for path {}", path.display())
95+
})?;
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+
};
93113
Ok(ProjectWorkspace::Cargo { cargo, sysroot })
94114
}
95115
}
@@ -403,11 +423,20 @@ pub fn get_rustc_cfg_options() -> CfgOptions {
403423
}
404424
}
405425

406-
match (|| -> Result<_> {
426+
match (|| -> Result<String> {
407427
// `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")?;
409432
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+
);
411440
}
412441
Ok(String::from_utf8(output.stdout)?)
413442
})() {

crates/ra_project_model/src/sysroot.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! FIXME: write short doc here
22
3+
use anyhow::{anyhow, bail, Context, Result};
34
use std::{
45
env,
56
path::{Path, PathBuf},
@@ -8,8 +9,6 @@ use std::{
89

910
use ra_arena::{impl_arena_id, Arena, RawId};
1011

11-
use crate::Result;
12-
1312
#[derive(Default, Debug, Clone)]
1413
pub struct Sysroot {
1514
crates: Arena<SysrootCrate, SysrootCrateData>,
@@ -51,7 +50,7 @@ impl Sysroot {
5150
let src = try_find_src_path(cargo_toml)?;
5251

5352
if !src.exists() {
54-
Err(format!(
53+
Err(anyhow!(
5554
"can't load standard library from sysroot\n\
5655
{}\n\
5756
(discovered via `rustc --print sysroot`)\n\
@@ -100,9 +99,14 @@ fn try_find_src_path(cargo_toml: &Path) -> Result<PathBuf> {
10099
.current_dir(cargo_toml.parent().unwrap())
101100
.args(&["--print", "sysroot"])
102101
.output()
103-
.map_err(|e| format!("rustc --print sysroot failed: {}", e))?;
102+
.context("rustc --print sysroot failed")?;
104103
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+
};
106110
}
107111
let stdout = String::from_utf8(rustc_output.stdout)?;
108112
let sysroot_path = Path::new(stdout.trim());

0 commit comments

Comments
 (0)