diff --git a/src/cargo/lib.rs b/src/cargo/lib.rs index 1281619b28d..a5c94f73fa8 100644 --- a/src/cargo/lib.rs +++ b/src/cargo/lib.rs @@ -117,7 +117,7 @@ pub fn exit_with_error(err: CliError, shell: &mut Shell) -> ! { /// Displays an error, and all its causes, to stderr. pub fn display_error(err: &Error, shell: &mut Shell) { debug!("display_error; err={:?}", err); - let has_verbose = _display_error(err, shell); + let has_verbose = _display_error(err, shell, true); if has_verbose { drop(writeln!( shell.err(), @@ -140,7 +140,15 @@ pub fn display_error(err: &Error, shell: &mut Shell) { } } -fn _display_error(err: &Error, shell: &mut Shell) -> bool { +/// Displays a warning, with an error object providing detailed information +/// and context. +pub fn display_warning_with_error(warning: &str, err: &Error, shell: &mut Shell) { + drop(shell.warn(warning)); + drop(writeln!(shell.err(), "")); + _display_error(err, shell, false); +} + +fn _display_error(err: &Error, shell: &mut Shell, as_err: bool) -> bool { let verbosity = shell.verbosity(); let is_verbose = |e: &(dyn std::error::Error + 'static)| -> bool { verbosity != Verbose && e.downcast_ref::().is_some() @@ -149,7 +157,11 @@ fn _display_error(err: &Error, shell: &mut Shell) -> bool { if is_verbose(err.as_ref()) { return true; } - drop(shell.error(&err)); + if as_err { + drop(shell.error(&err)); + } else { + drop(writeln!(shell.err(), "{}", err)); + } for cause in err.chain().skip(1) { // If we're not in verbose mode then print remaining errors until one // marked as `VerboseError` appears. diff --git a/src/cargo/ops/cargo_doc.rs b/src/cargo/ops/cargo_doc.rs index 85b2e0909bd..f67035fc7cd 100644 --- a/src/cargo/ops/cargo_doc.rs +++ b/src/cargo/ops/cargo_doc.rs @@ -104,10 +104,8 @@ fn open_docs(path: &Path, shell: &mut Shell) -> CargoResult<()> { } None => { if let Err(e) = opener::open(&path) { - shell.warn(format!("Couldn't open docs: {}", e))?; - for cause in anyhow::Error::new(e).chain().skip(1) { - shell.warn(format!("Caused by:\n {}", cause))?; - } + let e = e.into(); + crate::display_warning_with_error("couldn't open docs", &e, shell); } } }; diff --git a/src/cargo/ops/cargo_new.rs b/src/cargo/ops/cargo_new.rs index f9811f7a690..a78639aa2ed 100644 --- a/src/cargo/ops/cargo_new.rs +++ b/src/cargo/ops/cargo_new.rs @@ -762,12 +762,12 @@ mod tests { } if let Err(e) = Workspace::new(&path.join("Cargo.toml"), config) { - let msg = format!( + crate::display_warning_with_error( "compiling this new crate may not work due to invalid \ - workspace configuration\n\n{:?}", - e, + workspace configuration", + &e, + &mut config.shell(), ); - config.shell().warn(msg)?; } Ok(()) diff --git a/tests/testsuite/workspaces.rs b/tests/testsuite/workspaces.rs index 75ce5f79e4c..a3390f16cd5 100644 --- a/tests/testsuite/workspaces.rs +++ b/tests/testsuite/workspaces.rs @@ -1037,8 +1037,7 @@ fn new_warns_you_this_will_not_work() { .env("USER", "foo") .with_stderr( "\ -warning: compiling this new crate may not work due to invalid workspace \ -configuration +warning: compiling this new crate may not work due to invalid workspace configuration current package believes it's in a workspace when it's not: current: [..] @@ -1065,8 +1064,10 @@ fn new_warning_with_corrupt_ws() { failed to parse manifest at `[..]foo/Cargo.toml` Caused by: - 0: could not parse input as TOML - 1: expected an equals, found eof at line 1 column 5 + could not parse input as TOML + +Caused by: + expected an equals, found eof at line 1 column 5 Created binary (application) `bar` package ", )