summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJesús Lapastora <cyber.gsuscode@gmail.com>2022-02-06 23:04:28 +0100
committerGitHub <noreply@github.com>2022-02-06 23:04:28 +0100
commitc3cc40d2ac6f93b5e16177c274861b8f9c860e98 (patch)
treed6a3dc6aab5847dbf5a937e04c16697d0727ea66 /src
parent589576d3eb643dad0dd88dc5df0236625497177a (diff)
feat(cli): Print arguments if argument parsing fails (#3560)
* fix(#3554): Print the command line argv on clap error This is a very bare implementation that just prints the error and then a note with the arguments passed, it does this manually and doesn't use clap. I've also chosen to use `Vec`'s `Debug` implementation instead of rolling my own one because I thought it was good enough, but there might be a better way of doing all this. Altogether, I think this will be very useful to help in the diagnostic of other bugs :) * fix(#3554): Print the command line argv on clap error This is a very bare implementation that just prints the error and then a note with the arguments passed, it does this manually and doesn't use clap. I've also chosen to use `Vec`'s `Debug` implementation instead of rolling my own one because I thought it was good enough, but there might be a better way of doing all this. Altogether, I think this will be very useful to help in the diagnostic of other bugs :) EDIT: removed `dbg!`, set it to exit always. * correctness(exit): don't print argv / exit with error on help and version error kinds * fix: Avoid panicking when stdout/stderr closing unexpectedly * refactor(cli): use `use_stderr` instead of manual match for error kinds `clap` uses `use_stderr` to reliably check whether the error given is actually an error coming from user input or rather a hint to display other info (version, help, etc.) Also reworded/moved a couple of comments so that they explain better what is the thought process behind the code
Diffstat (limited to 'src')
-rw-r--r--src/main.rs33
1 files changed, 32 insertions, 1 deletions
diff --git a/src/main.rs b/src/main.rs
index c41926d41..a2dfad57f 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -108,7 +108,38 @@ fn main() {
let _ = ansi_term::enable_ansi_support();
logger::init();
- let args = Cli::parse();
+ let args = match Cli::try_parse() {
+ Ok(args) => args,
+ Err(e) => {
+ // if the error is not printed to stderr, this means it was not really
+ // an error but rather some information is going to be listed, therefore
+ // we won't print the arguments passed
+ let is_info_only = !e.use_stderr();
+ // print the error and void panicking in case of stdout/stderr closing unexpectedly
+ let _ = e.print();
+ // if there was no mistake by the user and we're only going to display information,
+ // we won't put arguments or exit with non-zero code
+ let exit_code = if is_info_only {
+ 0
+ } else {
+ // print the arguments
+ // avoid panicking in case of stderr closing
+ let mut stderr = io::stderr();
+ use io::Write;
+ let _ = writeln!(
+ stderr,
+ "\nNOTE:\n passed arguments: {:?}",
+ // collect into a vec to format args as a slice
+ std::env::args().skip(1).collect::<Vec<_>>()
+ );
+ // clap exits with status 2 on error:
+ // https://docs.rs/clap/latest/clap/struct.Error.html#method.exit
+ 2
+ };
+
+ std::process::exit(exit_code);
+ }
+ };
log::trace!("Parsed arguments: {:#?}", args);
match args.command {