Skip to content

Commit d7b45f9

Browse files
committed
Use context to create a chain of errors
There's an existing bug (#7782) in Cargo which exacerbates the issue here but in general having a stack of errors is a bit easier to read and work with than having a big long error message.
1 parent d4ccae3 commit d7b45f9

File tree

4 files changed

+69
-39
lines changed

4 files changed

+69
-39
lines changed

src/cargo/util/config/de.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -468,9 +468,9 @@ impl<'de, 'config> de::MapAccess<'de> for ValueDeserializer<'config> {
468468
// If this is the first time around we deserialize the `value` field
469469
// which is the actual deserializer
470470
if self.hits == 1 {
471-
return seed.deserialize(self.de.clone()).map_err(|e| {
472-
e.with_key_context(&self.de.key, self.definition.clone())
473-
});
471+
return seed
472+
.deserialize(self.de.clone())
473+
.map_err(|e| e.with_key_context(&self.de.key, self.definition.clone()));
474474
}
475475

476476
// ... otherwise we're deserializing the `definition` field, so we need

src/cargo/util/config/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1236,7 +1236,8 @@ impl ConfigError {
12361236

12371237
fn with_key_context(self, key: &ConfigKey, definition: Definition) -> ConfigError {
12381238
ConfigError {
1239-
error: anyhow!("could not load config key `{}`: {}", key, self),
1239+
error: anyhow::Error::from(self)
1240+
.context(format!("could not load config key `{}`", key)),
12401241
definition: Some(definition),
12411242
}
12421243
}

tests/testsuite/bad_config.rs

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,10 @@ fn bad_cargo_config_jobs() {
155155
.with_stderr(
156156
"\
157157
[ERROR] error in [..].cargo/config: \
158-
could not load config key `build.jobs`: \
159-
invalid value: integer `-1`, expected u32
158+
could not load config key `build.jobs`
159+
160+
Caused by:
161+
invalid value: integer `-1`, expected u32
160162
",
161163
)
162164
.run();
@@ -1102,8 +1104,12 @@ fn bad_source_config6() {
11021104
p.cargo("build")
11031105
.with_status(101)
11041106
.with_stderr(
1105-
"[ERROR] error in [..]/foo/.cargo/config: `source.crates-io.replace-with` \
1106-
expected a string, but found a array",
1107+
"\
1108+
[ERROR] error in [..]/foo/.cargo/config: could not load config key `source.crates-io.replace-with`
1109+
1110+
Caused by:
1111+
error in [..]/foo/.cargo/config: `source.crates-io.replace-with` expected a string, but found a array
1112+
"
11071113
)
11081114
.run();
11091115
}
@@ -1342,11 +1348,15 @@ fn bad_target_cfg() {
13421348
.with_stderr(
13431349
"\
13441350
[ERROR] error in [..]/foo/.cargo/config: \
1345-
could not load config key `target.cfg(not(target_os = \"none\")).runner`: \
1346-
error in [..]/foo/.cargo/config: \
1347-
could not load config key `target.cfg(not(target_os = \"none\")).runner`: \
1348-
failed to deserialize, expected a string or array of strings: \
1349-
data did not match any variant of untagged enum Target
1351+
could not load config key `target.cfg(not(target_os = \"none\")).runner`
1352+
1353+
Caused by:
1354+
error in [..]/foo/.cargo/config: \
1355+
could not load config key `target.cfg(not(target_os = \"none\")).runner`
1356+
1357+
Caused by:
1358+
failed to deserialize, expected a string or array of strings: \
1359+
data did not match any variant of untagged enum Target
13501360
",
13511361
)
13521362
.run();

tests/testsuite/config.rs

Lines changed: 45 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -495,9 +495,11 @@ c = ['c']
495495
let config = ConfigBuilder::new().env("CARGO_A", "x y").build();
496496
assert_error(
497497
config.get::<VSOB>("a").unwrap_err(),
498-
"error in environment variable `CARGO_A`: \
499-
could not load config key `a`: \
500-
invalid type: string \"x y\", expected a boolean or vector of strings",
498+
"\
499+
error in environment variable `CARGO_A`: could not load config key `a`
500+
501+
Caused by:
502+
invalid type: string \"x y\", expected a boolean or vector of strings",
501503
);
502504

503505
// Normal env.
@@ -570,9 +572,11 @@ opt-level = 'foo'
570572

571573
assert_error(
572574
config.get::<toml::TomlProfile>("profile.dev").unwrap_err(),
573-
"error in [..]/.cargo/config: \
574-
could not load config key `profile.dev.opt-level`: \
575-
must be an integer, `z`, or `s`, but found: foo",
575+
"\
576+
error in [..]/.cargo/config: could not load config key `profile.dev.opt-level`
577+
578+
Caused by:
579+
must be an integer, `z`, or `s`, but found: foo",
576580
);
577581

578582
let config = ConfigBuilder::new()
@@ -581,9 +585,11 @@ opt-level = 'foo'
581585

582586
assert_error(
583587
config.get::<toml::TomlProfile>("profile.dev").unwrap_err(),
584-
"error in environment variable `CARGO_PROFILE_DEV_OPT_LEVEL`: \
585-
could not load config key `profile.dev.opt-level`: \
586-
must be an integer, `z`, or `s`, but found: asdf",
588+
"\
589+
error in environment variable `CARGO_PROFILE_DEV_OPT_LEVEL`: could not load config key `profile.dev.opt-level`
590+
591+
Caused by:
592+
must be an integer, `z`, or `s`, but found: asdf",
587593
);
588594
}
589595

@@ -653,8 +659,11 @@ big = 123456789
653659
);
654660
assert_error(
655661
config.get::<u8>("S.big").unwrap_err(),
656-
"error in [..].cargo/config: could not load config key `S.big`: \
657-
invalid value: integer `123456789`, expected u8",
662+
"\
663+
error in [..].cargo/config: could not load config key `S.big`
664+
665+
Caused by:
666+
invalid value: integer `123456789`, expected u8",
658667
);
659668

660669
// Environment variable type errors.
@@ -664,9 +673,11 @@ big = 123456789
664673
);
665674
assert_error(
666675
config.get::<i8>("e.big").unwrap_err(),
667-
"error in environment variable `CARGO_E_BIG`: \
668-
could not load config key `e.big`: \
669-
invalid value: integer `123456789`, expected i8",
676+
"\
677+
error in environment variable `CARGO_E_BIG`: could not load config key `e.big`
678+
679+
Caused by:
680+
invalid value: integer `123456789`, expected i8",
670681
);
671682

672683
#[derive(Debug, Deserialize)]
@@ -952,27 +963,35 @@ i64max = 9223372036854775807
952963

953964
assert_error(
954965
config.get::<u32>("nneg").unwrap_err(),
955-
"error in [..].cargo/config: \
956-
could not load config key `nneg`: \
957-
invalid value: integer `-123456789`, expected u32",
966+
"\
967+
error in [..].cargo/config: could not load config key `nneg`
968+
969+
Caused by:
970+
invalid value: integer `-123456789`, expected u32",
958971
);
959972
assert_error(
960973
config.get::<u32>("eneg").unwrap_err(),
961-
"error in environment variable `CARGO_ENEG`: \
962-
could not load config key `eneg`: \
963-
invalid value: integer `-1`, expected u32",
974+
"\
975+
error in environment variable `CARGO_ENEG`: could not load config key `eneg`
976+
977+
Caused by:
978+
invalid value: integer `-1`, expected u32",
964979
);
965980
assert_error(
966981
config.get::<i8>("npos").unwrap_err(),
967-
"error in [..].cargo/config: \
968-
could not load config key `npos`: \
969-
invalid value: integer `123456789`, expected i8",
982+
"\
983+
error in [..].cargo/config: could not load config key `npos`
984+
985+
Caused by:
986+
invalid value: integer `123456789`, expected i8",
970987
);
971988
assert_error(
972989
config.get::<i8>("epos").unwrap_err(),
973-
"error in environment variable `CARGO_EPOS`: \
974-
could not load config key `epos`: \
975-
invalid value: integer `123456789`, expected i8",
990+
"\
991+
error in environment variable `CARGO_EPOS`: could not load config key `epos`
992+
993+
Caused by:
994+
invalid value: integer `123456789`, expected i8",
976995
);
977996
}
978997

0 commit comments

Comments
 (0)