1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#![warn(rust_2018_idioms)]
#![cfg_attr(test, deny(warnings))]
#![allow(clippy::all)]
use crate::core::shell::Verbosity::Verbose;
use crate::core::Shell;
use anyhow::Error;
use log::debug;
pub use crate::util::errors::{AlreadyPrintedError, InternalError, VerboseError};
pub use crate::util::{indented_lines, CargoResult, CliError, CliResult, Config};
pub use crate::version::version;
pub const CARGO_ENV: &str = "CARGO";
#[macro_use]
mod macros;
pub mod core;
pub mod ops;
pub mod sources;
pub mod util;
mod version;
pub fn exit_with_error(err: CliError, shell: &mut Shell) -> ! {
debug!("exit_with_error; err={:?}", err);
if let Some(ref err) = err.error {
if let Some(clap_err) = err.downcast_ref::<clap::Error>() {
let exit_code = if clap_err.use_stderr() { 1 } else { 0 };
let _ = clap_err.print();
std::process::exit(exit_code)
}
}
let CliError { error, exit_code } = err;
if let Some(error) = error {
display_error(&error, shell);
}
std::process::exit(exit_code)
}
pub fn display_error(err: &Error, shell: &mut Shell) {
debug!("display_error; err={:?}", err);
_display_error(err, shell, true);
if err
.chain()
.any(|e| e.downcast_ref::<InternalError>().is_some())
{
drop(shell.note("this is an unexpected cargo internal error"));
drop(
shell.note(
"we would appreciate a bug report: https://github.com/rust-lang/cargo/issues/",
),
);
drop(shell.note(format!("cargo {}", version())));
}
}
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 {
for (i, err) in err.chain().enumerate() {
if shell.verbosity() != Verbose && err.is::<VerboseError>() {
return true;
}
if err.is::<AlreadyPrintedError>() {
break;
}
if i == 0 {
if as_err {
drop(shell.error(&err));
} else {
drop(writeln!(shell.err(), "{}", err));
}
} else {
drop(writeln!(shell.err(), "\nCaused by:"));
drop(write!(shell.err(), "{}", indented_lines(&err.to_string())));
}
}
false
}