Skip to content

Commit e0dfa08

Browse files
committed
Auto merge of #8627 - ehuss:run-proc-err, r=Eh2406
Show full error context on `cargo run` error. If there was an error exec-ing a process with `cargo run`, the error message was not displayed. The code was calling `downcast` to a `ProcessError` which erased the surrounding error context. As shown in the modified test, it should now include a `Caused by:` message with the underlying error message.
2 parents 4de00d2 + 18bc90c commit e0dfa08

File tree

3 files changed

+40
-35
lines changed

3 files changed

+40
-35
lines changed

src/bin/cargo/commands/run.rs

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::command_prelude::*;
2-
2+
use crate::util::ProcessError;
33
use cargo::core::Verbosity;
44
use cargo::ops::{self, CompileFilter};
55

@@ -68,26 +68,29 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
6868
};
6969
}
7070
};
71-
match ops::run(&ws, &compile_opts, &values_os(args, "args"))? {
72-
None => Ok(()),
73-
Some(err) => {
74-
// If we never actually spawned the process then that sounds pretty
75-
// bad and we always want to forward that up.
76-
let exit = match err.exit {
77-
Some(exit) => exit,
78-
None => return Err(CliError::new(err.into(), 101)),
79-
};
8071

81-
// If `-q` was passed then we suppress extra error information about
82-
// a failed process, we assume the process itself printed out enough
83-
// information about why it failed so we don't do so as well
84-
let exit_code = exit.code().unwrap_or(101);
85-
let is_quiet = config.shell().verbosity() == Verbosity::Quiet;
86-
Err(if is_quiet {
87-
CliError::code(exit_code)
88-
} else {
89-
CliError::new(err.into(), exit_code)
90-
})
72+
ops::run(&ws, &compile_opts, &values_os(args, "args")).map_err(|err| {
73+
let proc_err = match err.downcast_ref::<ProcessError>() {
74+
Some(e) => e,
75+
None => return CliError::new(err.into(), 101),
76+
};
77+
78+
// If we never actually spawned the process then that sounds pretty
79+
// bad and we always want to forward that up.
80+
let exit = match proc_err.exit {
81+
Some(exit) => exit,
82+
None => return CliError::new(err.into(), 101),
83+
};
84+
85+
// If `-q` was passed then we suppress extra error information about
86+
// a failed process, we assume the process itself printed out enough
87+
// information about why it failed so we don't do so as well
88+
let exit_code = exit.code().unwrap_or(101);
89+
let is_quiet = config.shell().verbosity() == Verbosity::Quiet;
90+
if is_quiet {
91+
CliError::code(exit_code)
92+
} else {
93+
CliError::new(err.into(), exit_code)
9194
}
92-
}
95+
})
9396
}

src/cargo/ops/cargo_run.rs

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ use std::path::Path;
44

55
use crate::core::{TargetKind, Workspace};
66
use crate::ops;
7-
use crate::util::{CargoResult, ProcessError};
7+
use crate::util::CargoResult;
88

99
pub fn run(
1010
ws: &Workspace<'_>,
1111
options: &ops::CompileOptions,
1212
args: &[OsString],
13-
) -> CargoResult<Option<ProcessError>> {
13+
) -> CargoResult<()> {
1414
let config = ws.config();
1515

1616
// We compute the `bins` here *just for diagnosis*. The actual set of
@@ -87,13 +87,5 @@ pub fn run(
8787

8888
config.shell().status("Running", process.to_string())?;
8989

90-
let result = process.exec_replace();
91-
92-
match result {
93-
Ok(()) => Ok(None),
94-
Err(e) => {
95-
let err = e.downcast::<ProcessError>()?;
96-
Ok(Some(err))
97-
}
98-
}
90+
process.exec_replace()
9991
}

tests/testsuite/tool_paths.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//! Tests for configuration values that point to programs.
22
3-
use cargo_test_support::rustc_host;
4-
use cargo_test_support::{basic_lib_manifest, project};
3+
use cargo_test_support::{basic_lib_manifest, no_such_file_err_msg, project, rustc_host};
54

65
#[cargo_test]
76
fn pathless_tools() {
@@ -274,7 +273,18 @@ fn custom_runner_env() {
274273
p.cargo("run")
275274
.env(&key, "nonexistent-runner --foo")
276275
.with_status(101)
277-
.with_stderr_contains("[RUNNING] `nonexistent-runner --foo target/debug/foo[EXE]`")
276+
.with_stderr(&format!(
277+
"\
278+
[COMPILING] foo [..]
279+
[FINISHED] dev [..]
280+
[RUNNING] `nonexistent-runner --foo target/debug/foo[EXE]`
281+
[ERROR] could not execute process `nonexistent-runner --foo target/debug/foo[EXE]` (never executed)
282+
283+
Caused by:
284+
{}
285+
",
286+
no_such_file_err_msg()
287+
))
278288
.run();
279289
}
280290

0 commit comments

Comments
 (0)