Skip to content

Commit 37cffbe

Browse files
committed
Start migration to the failure crate
This commit is the initial steps to migrate Cargo's error handling from the `error-chain` crate to the `failure` crate. This is intended to be a low-cost (in terms of diff) transition where possible so it's note "purely idiomatic `failure` crate" just yet. The `error-chain` dependency is dropped in this commit and Cargo now canonically uses the `Error` type from the `failure` crate. The main last remnant of `error-chain` is a custom local extension trait to use `chain_err` instead of `with_context`. I'll try to follow up with a commit that renames this later but I wanted to make sure everything worked first! (and `chain_err` is used practically everywhere). Some minor tweaks happened in the tests as I touched up a few error messages here and there but overall the UI of Cargo should be exactly the same before and after this commit.
1 parent 4bbfc70 commit 37cffbe

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+511
-589
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ crypto-hash = "0.3"
2424
curl = "0.4.6"
2525
docopt = "0.8.1"
2626
env_logger = "0.4"
27-
error-chain = "0.11.0"
27+
failure = "0.1.1"
2828
filetime = "0.1"
2929
flate2 = "0.2"
3030
fs2 = "0.4"

src/bin/bench.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::env;
22

33
use cargo::core::Workspace;
44
use cargo::ops::{self, MessageFormat, Packages};
5-
use cargo::util::{CliResult, CliError, Config, CargoErrorKind};
5+
use cargo::util::{CliResult, CliError, Config};
66
use cargo::util::important_paths::{find_root_manifest_for_wd};
77

88
#[derive(Deserialize)]
@@ -144,8 +144,8 @@ pub fn execute(options: Options, config: &mut Config) -> CliResult {
144144
None => Ok(()),
145145
Some(err) => {
146146
Err(match err.exit.as_ref().and_then(|e| e.code()) {
147-
Some(i) => CliError::new("bench failed".into(), i),
148-
None => CliError::new(CargoErrorKind::CargoTestErrorKind(err).into(), 101)
147+
Some(i) => CliError::new(format_err!("bench failed"), i),
148+
None => CliError::new(err.into(), 101)
149149
})
150150
}
151151
}

src/bin/cargo.rs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
extern crate cargo;
22
extern crate env_logger;
3+
#[macro_use]
4+
extern crate failure;
35
extern crate git2_curl;
46
extern crate toml;
57
#[macro_use]
@@ -15,8 +17,8 @@ use std::fs;
1517
use std::path::{Path, PathBuf};
1618

1719
use cargo::core::shell::{Shell, Verbosity};
18-
use cargo::util::{self, CliResult, lev_distance, Config, CargoResult, CargoError, CargoErrorKind};
19-
use cargo::util::CliError;
20+
use cargo::util::{self, CliResult, lev_distance, Config, CargoResult};
21+
use cargo::util::{CliError, ProcessError};
2022

2123
#[derive(Deserialize)]
2224
pub struct Flags {
@@ -87,7 +89,7 @@ fn main() {
8789
let args: Vec<_> = try!(env::args_os()
8890
.map(|s| {
8991
s.into_string().map_err(|s| {
90-
CargoError::from(format!("invalid unicode in argument: {:?}", s))
92+
format_err!("invalid unicode in argument: {:?}", s)
9193
})
9294
})
9395
.collect());
@@ -315,15 +317,15 @@ fn execute_external_subcommand(config: &Config, cmd: &str, args: &[String]) -> C
315317
let command = match path {
316318
Some(command) => command,
317319
None => {
318-
return Err(CargoError::from(match find_closest(config, cmd) {
319-
Some(closest) => {
320-
format!("no such subcommand: `{}`\n\n\tDid you mean `{}`?\n",
320+
let err = match find_closest(config, cmd) {
321+
Some(closest) => {
322+
format_err!("no such subcommand: `{}`\n\n\tDid you mean `{}`?\n",
321323
cmd,
322324
closest)
323-
}
324-
None => format!("no such subcommand: `{}`", cmd),
325-
})
326-
.into())
325+
}
326+
None => format_err!("no such subcommand: `{}`", cmd),
327+
};
328+
return Err(CliError::new(err, 101))
327329
}
328330
};
329331

@@ -336,7 +338,7 @@ fn execute_external_subcommand(config: &Config, cmd: &str, args: &[String]) -> C
336338
Err(e) => e,
337339
};
338340

339-
if let &CargoErrorKind::ProcessErrorKind(ref perr) = err.kind() {
341+
if let Some(perr) = err.downcast_ref::<ProcessError>() {
340342
if let Some(code) = perr.exit.as_ref().and_then(|c| c.code()) {
341343
return Err(CliError::code(code));
342344
}

src/bin/check.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,8 @@ pub fn execute(options: Options, config: &mut Config) -> CliResult {
114114
Some("test") => true,
115115
None => false,
116116
Some(profile) => {
117-
let err = format!("unknown profile: `{}`, only `test` is currently supported",
118-
profile).into();
117+
let err = format_err!("unknown profile: `{}`, only `test` is \
118+
currently supported", profile);
119119
return Err(CliError::new(err, 101))
120120
}
121121
};

src/bin/help.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,6 @@ pub fn execute(_: Options, _: &mut Config) -> CliResult {
1818
// This is a dummy command just so that `cargo help help` works.
1919
// The actual delegation of help flag to subcommands is handled by the
2020
// cargo command.
21-
Err(CliError::new("help command should not be executed directly".into(), 101))
21+
Err(CliError::new(format_err!("help command should not be executed directly"),
22+
101))
2223
}

src/bin/install.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use cargo::ops;
22
use cargo::core::{SourceId, GitReference};
3-
use cargo::util::{CargoError, CliResult, Config, ToUrl};
3+
use cargo::util::{CliResult, Config, ToUrl};
44

55
#[derive(Deserialize)]
66
pub struct Options {
@@ -154,7 +154,7 @@ pub fn execute(options: Options, config: &mut Config) -> CliResult {
154154

155155
let krates = options.arg_crate.iter().map(|s| &s[..]).collect::<Vec<_>>();
156156
let vers = match (&options.flag_vers, &options.flag_version) {
157-
(&Some(_), &Some(_)) => return Err(CargoError::from("Invalid arguments.").into()),
157+
(&Some(_), &Some(_)) => return Err(format_err!("invalid arguments").into()),
158158
(&Some(ref v), _) | (_, &Some(ref v)) => Some(v.as_ref()),
159159
_ => None,
160160
};

src/bin/locate_project.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ pub fn execute(flags: LocateProjectFlags, config: &mut Config) -> CliResult {
2727
let root = find_root_manifest_for_wd(flags.flag_manifest_path, config.cwd())?;
2828

2929
let string = root.to_str()
30-
.ok_or_else(|| "Your project path contains \
31-
characters not representable in \
32-
Unicode".into())
30+
.ok_or_else(|| format_err!("your project path contains \
31+
characters not representable in \
32+
Unicode"))
3333
.map_err(|e| CliError::new(e, 1))?;
3434

3535
let location = ProjectLocation { root: string.to_string() };

src/bin/login.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::io;
44
use cargo::ops;
55
use cargo::core::{SourceId, Source};
66
use cargo::sources::RegistrySource;
7-
use cargo::util::{CargoError, CliResult, CargoResultExt, Config};
7+
use cargo::util::{CliResult, CargoResultExt, Config, CargoError};
88

99
#[derive(Deserialize)]
1010
pub struct Options {
@@ -48,15 +48,17 @@ pub fn execute(options: Options, config: &mut Config) -> CliResult {
4848
&options.flag_z)?;
4949

5050
if options.flag_registry.is_some() && !config.cli_unstable().unstable_options {
51-
return Err(CargoError::from("registry option is an unstable feature and requires -Zunstable-options to use.").into());
51+
return Err(format_err!("registry option is an unstable feature and \
52+
requires -Zunstable-options to use.").into());
5253
}
5354

5455
let token = match options.arg_token {
5556
Some(token) => token,
5657
None => {
5758
let host = match options.flag_registry {
5859
Some(ref _registry) => {
59-
return Err(CargoError::from("token must be provided when --registry is provided.").into());
60+
return Err(format_err!("token must be provided when \
61+
--registry is provided.").into())
6062
}
6163
None => {
6264
let src = SourceId::crates_io(config)?;
@@ -71,7 +73,7 @@ pub fn execute(options: Options, config: &mut Config) -> CliResult {
7173
let input = io::stdin();
7274
input.lock().read_line(&mut line).chain_err(|| {
7375
"failed to read stdin"
74-
})?;
76+
}).map_err(CargoError::from)?;
7577
line.trim().to_string()
7678
}
7779
};

src/bin/owner.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use cargo::ops;
2-
use cargo::util::{CargoError, CliResult, Config};
2+
use cargo::util::{CliResult, Config};
33

44
#[derive(Deserialize)]
55
pub struct Options {
@@ -67,7 +67,8 @@ pub fn execute(options: Options, config: &mut Config) -> CliResult {
6767
};
6868

6969
if opts.registry.is_some() && !config.cli_unstable().unstable_options {
70-
return Err(CargoError::from("registry option is an unstable feature and requires -Zunstable-options to use.").into());
70+
return Err(format_err!("registry option is an unstable feature and \
71+
requires -Zunstable-options to use.").into())
7172
}
7273

7374
ops::modify_owners(config, &opts)?;

src/bin/publish.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use cargo::core::Workspace;
22
use cargo::ops;
3-
use cargo::util::{CargoError, CliResult, Config};
3+
use cargo::util::{CliResult, Config};
44
use cargo::util::important_paths::find_root_manifest_for_wd;
55

66
#[derive(Deserialize)]
@@ -74,7 +74,8 @@ pub fn execute(options: Options, config: &mut Config) -> CliResult {
7474
} = options;
7575

7676
if registry.is_some() && !config.cli_unstable().unstable_options {
77-
return Err(CargoError::from("registry option is an unstable feature and requires -Zunstable-options to use.").into());
77+
return Err(format_err!("registry option is an unstable feature and \
78+
requires -Zunstable-options to use.").into())
7879
}
7980

8081
// TODO: Deprecated

src/bin/run.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::iter::FromIterator;
22

33
use cargo::core::Workspace;
44
use cargo::ops::{self, MessageFormat, Packages};
5-
use cargo::util::{CliResult, CliError, Config, CargoErrorKind};
5+
use cargo::util::{CliResult, CliError, Config};
66
use cargo::util::important_paths::{find_root_manifest_for_wd};
77

88
#[derive(Deserialize)]
@@ -118,8 +118,7 @@ pub fn execute(options: Options, config: &mut Config) -> CliResult {
118118
// bad and we always want to forward that up.
119119
let exit = match err.exit {
120120
Some(exit) => exit,
121-
None => return Err(
122-
CliError::new(CargoErrorKind::ProcessErrorKind(err).into(), 101)),
121+
None => return Err(CliError::new(err.into(), 101)),
123122
};
124123

125124
// If `-q` was passed then we suppress extra error information about
@@ -129,7 +128,7 @@ pub fn execute(options: Options, config: &mut Config) -> CliResult {
129128
Err(if options.flag_quiet == Some(true) {
130129
CliError::code(exit_code)
131130
} else {
132-
CliError::new(CargoErrorKind::ProcessErrorKind(err).into(), exit_code)
131+
CliError::new(err.into(), exit_code)
133132
})
134133
}
135134
}

src/bin/rustc.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,8 @@ pub fn execute(options: Options, config: &mut Config) -> CliResult {
104104
Some("bench") => CompileMode::Bench,
105105
Some("check") => CompileMode::Check {test: false},
106106
Some(mode) => {
107-
let err = format!("unknown profile: `{}`, use dev,
108-
test, or bench", mode).into();
107+
let err = format_err!("unknown profile: `{}`, use dev,
108+
test, or bench", mode);
109109
return Err(CliError::new(err, 101))
110110
}
111111
};

src/bin/search.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use cargo::ops;
2-
use cargo::util::{CargoError, CliResult, Config};
2+
use cargo::util::{CliResult, Config};
33

44
use std::cmp;
55

@@ -57,7 +57,8 @@ pub fn execute(options: Options, config: &mut Config) -> CliResult {
5757
} = options;
5858

5959
if registry.is_some() && !config.cli_unstable().unstable_options {
60-
return Err(CargoError::from("registry option is an unstable feature and requires -Zunstable-options to use.").into());
60+
return Err(format_err!("registry option is an unstable feature and \
61+
requires -Zunstable-options to use.").into())
6162
}
6263

6364
// TODO: Depricated

src/bin/test.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::env;
22

33
use cargo::core::Workspace;
44
use cargo::ops::{self, MessageFormat, Packages};
5-
use cargo::util::{CliResult, CliError, Config, CargoErrorKind};
5+
use cargo::util::{CliResult, CliError, Config};
66
use cargo::util::important_paths::find_root_manifest_for_wd;
77

88
#[derive(Deserialize)]
@@ -177,8 +177,8 @@ pub fn execute(options: Options, config: &mut Config) -> CliResult {
177177
None => Ok(()),
178178
Some(err) => {
179179
Err(match err.exit.as_ref().and_then(|e| e.code()) {
180-
Some(i) => CliError::new(err.hint().into(), i),
181-
None => CliError::new(CargoErrorKind::CargoTestErrorKind(err).into(), 101),
180+
Some(i) => CliError::new(format_err!("{}", err.hint()), i),
181+
None => CliError::new(err.into(), 101),
182182
})
183183
}
184184
}

src/bin/yank.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use cargo::ops;
2-
use cargo::util::{CargoError, CliResult, Config};
2+
use cargo::util::{CliResult, Config};
33

44
#[derive(Deserialize)]
55
pub struct Options {
@@ -56,7 +56,8 @@ pub fn execute(options: Options, config: &mut Config) -> CliResult {
5656
&options.flag_z)?;
5757

5858
if options.flag_registry.is_some() && !config.cli_unstable().unstable_options {
59-
return Err(CargoError::from("registry option is an unstable feature and requires -Zunstable-options to use.").into());
59+
return Err(format_err!("registry option is an unstable feature and \
60+
requires -Zunstable-options to use.").into())
6061
}
6162

6263
ops::yank(config,

src/cargo/core/dependency.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -350,9 +350,10 @@ impl FromStr for Platform {
350350
fn from_str(s: &str) -> CargoResult<Platform> {
351351
if s.starts_with("cfg(") && s.ends_with(')') {
352352
let s = &s[4..s.len()-1];
353-
s.parse().map(Platform::Cfg).chain_err(|| {
354-
format!("failed to parse `{}` as a cfg expression", s)
355-
})
353+
let p = s.parse().map(Platform::Cfg).chain_err(|| {
354+
format_err!("failed to parse `{}` as a cfg expression", s)
355+
})?;
356+
Ok(p)
356357
} else {
357358
Ok(Platform::Name(s.to_string()))
358359
}

src/cargo/core/manifest.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -332,8 +332,8 @@ impl Manifest {
332332
pub fn feature_gate(&self) -> CargoResult<()> {
333333
if self.im_a_teapot.is_some() {
334334
self.features.require(Feature::test_dummy_unstable()).chain_err(|| {
335-
"the `im-a-teapot` manifest key is unstable and may not work \
336-
properly in England"
335+
format_err!("the `im-a-teapot` manifest key is unstable and may \
336+
not work properly in England")
337337
})?;
338338
}
339339

src/cargo/core/package.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ impl<'cfg> PackageSet<'cfg> {
207207
internal(format!("couldn't find source for `{}`", id))
208208
})?;
209209
let pkg = source.download(id).chain_err(|| {
210-
"unable to get packages from source"
210+
format_err!("unable to get packages from source")
211211
})?;
212212
assert!(slot.fill(pkg).is_ok());
213213
Ok(slot.borrow().unwrap())

src/cargo/core/package_id_spec.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use url::Url;
66

77
use core::PackageId;
88
use util::{ToUrl, ToSemver};
9-
use util::errors::{CargoError, CargoResult, CargoResultExt};
9+
use util::errors::{CargoResult, CargoResultExt};
1010

1111
#[derive(Clone, PartialEq, Eq, Debug)]
1212
pub struct PackageIdSpec {
@@ -49,7 +49,7 @@ impl PackageIdSpec {
4949
where I: IntoIterator<Item=&'a PackageId>
5050
{
5151
let spec = PackageIdSpec::parse(spec).chain_err(|| {
52-
format!("invalid package id specification: `{}`", spec)
52+
format_err!("invalid package id specification: `{}`", spec)
5353
})?;
5454
spec.query(i)
5555
}
@@ -70,11 +70,11 @@ impl PackageIdSpec {
7070
url.set_fragment(None);
7171
let (name, version) = {
7272
let mut path = url.path_segments().ok_or_else(|| {
73-
CargoError::from(format!("pkgid urls must have a path: {}", url))
73+
format_err!("pkgid urls must have a path: {}", url)
7474
})?;
7575
let path_name = path.next_back().ok_or_else(|| {
76-
CargoError::from(format!("pkgid urls must have at least one path \
77-
component: {}", url))
76+
format_err!("pkgid urls must have at least one path \
77+
component: {}", url)
7878
})?;
7979
match frag {
8080
Some(fragment) => {
@@ -150,7 +150,7 @@ impl PackageIdSpec {
150150
let mut vec = vec![ret, other];
151151
vec.extend(ids);
152152
minimize(&mut msg, &vec, self);
153-
Err(msg.into())
153+
Err(format_err!("{}", msg))
154154
}
155155
None => Ok(ret)
156156
};

0 commit comments

Comments
 (0)