Skip to content

Commit 2202891

Browse files
committed
Split errors into WorkspaceError enum
1 parent 4516c4c commit 2202891

File tree

4 files changed

+89
-30
lines changed

4 files changed

+89
-30
lines changed

crates/ra_db/src/lib.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@ use ra_syntax::{ast, Parse, SourceFile, TextRange, TextUnit};
1010

1111
pub use crate::{
1212
cancellation::Canceled,
13-
input::{CrateGraph, CrateId, Dependency, Edition, Env, FileId, SourceRoot, SourceRootId},
13+
input::{
14+
CrateGraph, CrateId, Dependency, Edition, Env, FileId, ParseEditionError, SourceRoot,
15+
SourceRootId,
16+
},
1417
};
1518
pub use relative_path::{RelativePath, RelativePathBuf};
1619
pub use salsa;

crates/ra_project_model/src/cargo_workspace.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use ra_db::Edition;
88
use rustc_hash::FxHashMap;
99
use serde::Deserialize;
1010

11-
use crate::Result;
11+
use crate::WorkspaceError;
1212

1313
/// `CargoWorkspace` represents the logical structure of, well, a Cargo
1414
/// workspace. It pretty closely mirrors `cargo metadata` output.
@@ -156,7 +156,7 @@ impl CargoWorkspace {
156156
pub fn from_cargo_metadata(
157157
cargo_toml: &Path,
158158
cargo_features: &CargoFeatures,
159-
) -> Result<CargoWorkspace> {
159+
) -> Result<CargoWorkspace, WorkspaceError> {
160160
let mut meta = MetadataCommand::new();
161161
meta.manifest_path(cargo_toml);
162162
if cargo_features.all_features {
@@ -171,7 +171,7 @@ impl CargoWorkspace {
171171
if let Some(parent) = cargo_toml.parent() {
172172
meta.current_dir(parent);
173173
}
174-
let meta = meta.exec().map_err(|e| format!("cargo metadata failed: {}", e))?;
174+
let meta = meta.exec().map_err(|e| WorkspaceError::CargoMetadataFailed(e))?;
175175
let mut pkg_by_id = FxHashMap::default();
176176
let mut packages = Arena::default();
177177
let mut targets = Arena::default();

crates/ra_project_model/src/lib.rs

Lines changed: 73 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@ mod json_project;
55
mod sysroot;
66

77
use std::{
8-
error::Error,
8+
fmt,
99
fs::File,
1010
io::BufReader,
1111
path::{Path, PathBuf},
1212
process::Command,
1313
};
1414

1515
use ra_cfg::CfgOptions;
16-
use ra_db::{CrateGraph, CrateId, Edition, Env, FileId};
16+
use ra_db::{CrateGraph, CrateId, Edition, Env, FileId, ParseEditionError};
1717
use rustc_hash::FxHashMap;
1818
use serde_json::from_reader;
1919

@@ -23,8 +23,57 @@ pub use crate::{
2323
sysroot::Sysroot,
2424
};
2525

26-
// FIXME use proper error enum
27-
pub type Result<T> = ::std::result::Result<T, Box<dyn Error + Send + Sync>>;
26+
#[derive(Debug)]
27+
pub enum WorkspaceError {
28+
CargoMetadataFailed(cargo_metadata::Error),
29+
CargoTomlNotFound(PathBuf),
30+
NoStdLib(PathBuf),
31+
OpenWorkspaceError(std::io::Error),
32+
ParseEditionError(ParseEditionError),
33+
ReadWorkspaceError(serde_json::Error),
34+
RustcCfgError,
35+
RustcError(std::io::Error),
36+
RustcOutputError(std::string::FromUtf8Error),
37+
SysrootNotFound,
38+
}
39+
40+
impl fmt::Display for WorkspaceError {
41+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
42+
match self {
43+
Self::OpenWorkspaceError(err) | Self::RustcError(err) => write!(f, "{}", err),
44+
Self::ParseEditionError(err) => write!(f, "{}", err),
45+
Self::ReadWorkspaceError(err) => write!(f, "{}", err),
46+
Self::RustcOutputError(err) => write!(f, "{}", err),
47+
Self::CargoMetadataFailed(err) => write!(f, "cargo metadata failed: {}", err),
48+
Self::RustcCfgError => write!(f, "failed to get rustc cfgs"),
49+
Self::SysrootNotFound => write!(f, "failed to locate sysroot"),
50+
Self::CargoTomlNotFound(path) => {
51+
write!(f, "can't find Cargo.toml at {}", path.display())
52+
}
53+
Self::NoStdLib(sysroot) => write!(
54+
f,
55+
"can't load standard library from sysroot\n\
56+
{:?}\n\
57+
try running `rustup component add rust-src` or set `RUST_SRC_PATH`",
58+
sysroot,
59+
),
60+
}
61+
}
62+
}
63+
64+
impl std::error::Error for WorkspaceError {}
65+
66+
impl From<ParseEditionError> for WorkspaceError {
67+
fn from(err: ParseEditionError) -> Self {
68+
Self::ParseEditionError(err.into())
69+
}
70+
}
71+
72+
impl From<cargo_metadata::Error> for WorkspaceError {
73+
fn from(err: cargo_metadata::Error) -> Self {
74+
Self::CargoMetadataFailed(err.into())
75+
}
76+
}
2877

2978
#[derive(Debug, Clone)]
3079
pub enum ProjectWorkspace {
@@ -60,20 +109,27 @@ impl PackageRoot {
60109
}
61110

62111
impl ProjectWorkspace {
63-
pub fn discover(path: &Path, cargo_features: &CargoFeatures) -> Result<ProjectWorkspace> {
112+
pub fn discover(
113+
path: &Path,
114+
cargo_features: &CargoFeatures,
115+
) -> Result<ProjectWorkspace, WorkspaceError> {
64116
ProjectWorkspace::discover_with_sysroot(path, true, cargo_features)
65117
}
66118

67119
pub fn discover_with_sysroot(
68120
path: &Path,
69121
with_sysroot: bool,
70122
cargo_features: &CargoFeatures,
71-
) -> Result<ProjectWorkspace> {
123+
) -> Result<ProjectWorkspace, WorkspaceError> {
72124
match find_rust_project_json(path) {
73125
Some(json_path) => {
74-
let file = File::open(json_path)?;
126+
let file =
127+
File::open(json_path).map_err(|err| WorkspaceError::OpenWorkspaceError(err))?;
75128
let reader = BufReader::new(file);
76-
Ok(ProjectWorkspace::Json { project: from_reader(reader)? })
129+
Ok(ProjectWorkspace::Json {
130+
project: from_reader(reader)
131+
.map_err(|err| WorkspaceError::ReadWorkspaceError(err))?,
132+
})
77133
}
78134
None => {
79135
let cargo_toml = find_cargo_toml(path)?;
@@ -350,7 +406,7 @@ fn find_rust_project_json(path: &Path) -> Option<PathBuf> {
350406
None
351407
}
352408

353-
fn find_cargo_toml(path: &Path) -> Result<PathBuf> {
409+
fn find_cargo_toml(path: &Path) -> Result<PathBuf, WorkspaceError> {
354410
if path.ends_with("Cargo.toml") {
355411
return Ok(path.to_path_buf());
356412
}
@@ -362,7 +418,7 @@ fn find_cargo_toml(path: &Path) -> Result<PathBuf> {
362418
}
363419
curr = path.parent();
364420
}
365-
Err(format!("can't find Cargo.toml at {}", path.display()))?
421+
Err(WorkspaceError::CargoTomlNotFound(path.to_path_buf()))
366422
}
367423

368424
pub fn get_rustc_cfg_options() -> CfgOptions {
@@ -376,13 +432,16 @@ pub fn get_rustc_cfg_options() -> CfgOptions {
376432
}
377433
}
378434

379-
match (|| -> Result<_> {
435+
match (|| -> Result<_, WorkspaceError> {
380436
// `cfg(test)` and `cfg(debug_assertion)` are handled outside, so we suppress them here.
381-
let output = Command::new("rustc").args(&["--print", "cfg", "-O"]).output()?;
437+
let output = Command::new("rustc")
438+
.args(&["--print", "cfg", "-O"])
439+
.output()
440+
.map_err(|err| WorkspaceError::RustcError(err))?;
382441
if !output.status.success() {
383-
Err("failed to get rustc cfgs")?;
442+
Err(WorkspaceError::RustcCfgError)?;
384443
}
385-
Ok(String::from_utf8(output.stdout)?)
444+
Ok(String::from_utf8(output.stdout).map_err(|err| WorkspaceError::RustcOutputError(err))?)
386445
})() {
387446
Ok(rustc_cfgs) => {
388447
for line in rustc_cfgs.lines() {

crates/ra_project_model/src/sysroot.rs

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use std::{
88

99
use ra_arena::{impl_arena_id, Arena, RawId};
1010

11-
use crate::Result;
11+
use crate::WorkspaceError;
1212

1313
#[derive(Default, Debug, Clone)]
1414
pub struct Sysroot {
@@ -47,16 +47,11 @@ impl Sysroot {
4747
self.crates.iter().map(|(id, _data)| id)
4848
}
4949

50-
pub fn discover(cargo_toml: &Path) -> Result<Sysroot> {
50+
pub fn discover(cargo_toml: &Path) -> Result<Sysroot, WorkspaceError> {
5151
let src = try_find_src_path(cargo_toml)?;
5252

5353
if !src.exists() {
54-
Err(format!(
55-
"can't load standard library from sysroot\n\
56-
{:?}\n\
57-
try running `rustup component add rust-src` or set `RUST_SRC_PATH`",
58-
src,
59-
))?;
54+
return Err(WorkspaceError::NoStdLib(src));
6055
}
6156

6257
let mut sysroot = Sysroot { crates: Arena::default() };
@@ -90,19 +85,21 @@ impl Sysroot {
9085
}
9186
}
9287

93-
fn try_find_src_path(cargo_toml: &Path) -> Result<PathBuf> {
88+
fn try_find_src_path(cargo_toml: &Path) -> Result<PathBuf, WorkspaceError> {
9489
if let Ok(path) = env::var("RUST_SRC_PATH") {
9590
return Ok(path.into());
9691
}
9792

9893
let rustc_output = Command::new("rustc")
9994
.current_dir(cargo_toml.parent().unwrap())
10095
.args(&["--print", "sysroot"])
101-
.output()?;
96+
.output()
97+
.map_err(|err| WorkspaceError::RustcError(err))?;
10298
if !rustc_output.status.success() {
103-
Err("failed to locate sysroot")?;
99+
Err(WorkspaceError::SysrootNotFound)?;
104100
}
105-
let stdout = String::from_utf8(rustc_output.stdout)?;
101+
let stdout = String::from_utf8(rustc_output.stdout)
102+
.map_err(|err| WorkspaceError::RustcOutputError(err))?;
106103
let sysroot_path = Path::new(stdout.trim());
107104
Ok(sysroot_path.join("lib/rustlib/src/rust/src"))
108105
}

0 commit comments

Comments
 (0)