1use anyhow::Error;
2use log::debug;
3use util::errors::AlreadyPrintedError;
4use util::indented_lines;
5
6use crate::core::shell::Verbosity::Verbose;
7use crate::{core::Shell, util::errors::InternalError};
8
9use util::{errors::VerboseError, CliError};
10
11pub mod core;
12pub mod ops;
13pub mod util;
14pub mod templates;
15
16pub fn exit_with_error(err: CliError, shell: &mut Shell) -> ! {
17 debug!("exit_with_error; err={:?}", err);
18
19 if let Some(ref err) = err.error {
20 if let Some(clap_err) = err.downcast_ref::<clap::Error>() {
21 let exit_code = if clap_err.use_stderr() { 1 } else { 0 };
22 let _ = clap_err.print();
23 std::process::exit(exit_code)
24 }
25 }
26
27 let CliError { error, exit_code } = err;
28 if let Some(error) = error {
29 display_error(&error, shell);
30 }
31
32 std::process::exit(exit_code)
33}
34
35pub fn display_error(err: &Error, shell: &mut Shell) {
37 debug!("display_error; err={:?}", err);
38 _display_error(err, shell, true);
39 if err
40 .chain()
41 .any(|e| e.downcast_ref::<InternalError>().is_some())
42 {
43 drop(shell.note("this is an unexpected substrate-manager internal error"));
44 drop(
45 shell.note(
46 "we would appreciate a bug report: https://github.com/omerdn1/substrate-manager/issues/",
47 ),
48 );
49 }
52}
53
54fn _display_error(err: &Error, shell: &mut Shell, as_err: bool) -> bool {
55 for (i, err) in err.chain().enumerate() {
56 if shell.verbosity() != Verbose && err.is::<VerboseError>() {
61 return true;
62 }
63 if err.is::<AlreadyPrintedError>() {
64 break;
65 }
66 if i == 0 {
67 if as_err {
68 drop(shell.error(err));
69 } else {
70 drop(writeln!(shell.err(), "{}", err));
71 }
72 } else {
73 drop(writeln!(shell.err(), "\nCaused by:"));
74 drop(write!(shell.err(), "{}", indented_lines(&err.to_string())));
75 }
76 }
77 false
78}