1 // Std
2 use std::{
3     borrow::Cow,
4     convert::From,
5     error,
6     fmt::{self, Debug, Display, Formatter},
7     io::{self, BufRead},
8     result::Result as StdResult,
9 };
10 
11 // Internal
12 use crate::{
13     build::Arg,
14     output::fmt::Colorizer,
15     parse::features::suggestions,
16     util::{color::ColorChoice, safe_exit, SUCCESS_CODE, USAGE_CODE},
17     App, AppSettings,
18 };
19 
20 /// Short hand for [`Result`] type
21 ///
22 /// [`Result`]: std::result::Result
23 pub type Result<T> = StdResult<T, Error>;
24 
25 /// Command line argument parser kind of error
26 #[derive(Debug, Copy, Clone, PartialEq)]
27 #[non_exhaustive]
28 pub enum ErrorKind {
29     /// Occurs when an [`Arg`] has a set of possible values,
30     /// and the user provides a value which isn't in that set.
31     ///
32     /// # Examples
33     ///
34     /// ```rust
35     /// # use clap::{App, Arg, ErrorKind};
36     /// let result = App::new("prog")
37     ///     .arg(Arg::new("speed")
38     ///         .possible_value("fast")
39     ///         .possible_value("slow"))
40     ///     .try_get_matches_from(vec!["prog", "other"]);
41     /// assert!(result.is_err());
42     /// assert_eq!(result.unwrap_err().kind(), ErrorKind::InvalidValue);
43     /// ```
44     InvalidValue,
45 
46     /// Occurs when a user provides a flag, option, argument or subcommand which isn't defined.
47     ///
48     /// # Examples
49     ///
50     /// ```rust
51     /// # use clap::{App, arg, ErrorKind};
52     /// let result = App::new("prog")
53     ///     .arg(arg!(--flag "some flag"))
54     ///     .try_get_matches_from(vec!["prog", "--other"]);
55     /// assert!(result.is_err());
56     /// assert_eq!(result.unwrap_err().kind(), ErrorKind::UnknownArgument);
57     /// ```
58     UnknownArgument,
59 
60     /// Occurs when the user provides an unrecognized [`Subcommand`] which meets the threshold for
61     /// being similar enough to an existing subcommand.
62     /// If it doesn't meet the threshold, or the 'suggestions' feature is disabled,
63     /// the more general [`UnknownArgument`] error is returned.
64     ///
65     /// # Examples
66     ///
67     #[cfg_attr(not(feature = "suggestions"), doc = " ```no_run")]
68     #[cfg_attr(feature = "suggestions", doc = " ```")]
69     /// # use clap::{App, Arg, ErrorKind, };
70     /// let result = App::new("prog")
71     ///     .subcommand(App::new("config")
72     ///         .about("Used for configuration")
73     ///         .arg(Arg::new("config_file")
74     ///             .help("The configuration file to use")
75     ///             .index(1)))
76     ///     .try_get_matches_from(vec!["prog", "confi"]);
77     /// assert!(result.is_err());
78     /// assert_eq!(result.unwrap_err().kind(), ErrorKind::InvalidSubcommand);
79     /// ```
80     ///
81     /// [`Subcommand`]: crate::Subcommand
82     /// [`UnknownArgument`]: ErrorKind::UnknownArgument
83     InvalidSubcommand,
84 
85     /// Occurs when the user provides an unrecognized [`Subcommand`] which either
86     /// doesn't meet the threshold for being similar enough to an existing subcommand,
87     /// or the 'suggestions' feature is disabled.
88     /// Otherwise the more detailed [`InvalidSubcommand`] error is returned.
89     ///
90     /// This error typically happens when passing additional subcommand names to the `help`
91     /// subcommand. Otherwise, the more general [`UnknownArgument`] error is used.
92     ///
93     /// # Examples
94     ///
95     /// ```rust
96     /// # use clap::{App, Arg, ErrorKind, };
97     /// let result = App::new("prog")
98     ///     .subcommand(App::new("config")
99     ///         .about("Used for configuration")
100     ///         .arg(Arg::new("config_file")
101     ///             .help("The configuration file to use")
102     ///             .index(1)))
103     ///     .try_get_matches_from(vec!["prog", "help", "nothing"]);
104     /// assert!(result.is_err());
105     /// assert_eq!(result.unwrap_err().kind(), ErrorKind::UnrecognizedSubcommand);
106     /// ```
107     ///
108     /// [`Subcommand`]: crate::Subcommand
109     /// [`InvalidSubcommand`]: ErrorKind::InvalidSubcommand
110     /// [`UnknownArgument`]: ErrorKind::UnknownArgument
111     UnrecognizedSubcommand,
112 
113     /// Occurs when the user provides an empty value for an option that does not allow empty
114     /// values.
115     ///
116     /// # Examples
117     ///
118     /// ```rust
119     /// # use clap::{App, Arg, ErrorKind};
120     /// let res = App::new("prog")
121     ///     .arg(Arg::new("color")
122     ///          .takes_value(true)
123     ///          .forbid_empty_values(true)
124     ///          .long("color"))
125     ///     .try_get_matches_from(vec!["prog", "--color="]);
126     /// assert!(res.is_err());
127     /// assert_eq!(res.unwrap_err().kind(), ErrorKind::EmptyValue);
128     /// ```
129     EmptyValue,
130 
131     /// Occurs when the user doesn't use equals for an option that requires equal
132     /// sign to provide values.
133     ///
134     /// ```rust
135     /// # use clap::{App, Arg, ErrorKind};
136     /// let res = App::new("prog")
137     ///     .arg(Arg::new("color")
138     ///          .takes_value(true)
139     ///          .require_equals(true)
140     ///          .long("color"))
141     ///     .try_get_matches_from(vec!["prog", "--color", "red"]);
142     /// assert!(res.is_err());
143     /// assert_eq!(res.unwrap_err().kind(), ErrorKind::NoEquals);
144     /// ```
145     NoEquals,
146 
147     /// Occurs when the user provides a value for an argument with a custom validation and the
148     /// value fails that validation.
149     ///
150     /// # Examples
151     ///
152     /// ```rust
153     /// # use clap::{App, Arg, ErrorKind};
154     /// fn is_numeric(val: &str) -> Result<(), String> {
155     ///     match val.parse::<i64>() {
156     ///         Ok(..) => Ok(()),
157     ///         Err(..) => Err(String::from("Value wasn't a number!")),
158     ///     }
159     /// }
160     ///
161     /// let result = App::new("prog")
162     ///     .arg(Arg::new("num")
163     ///          .validator(is_numeric))
164     ///     .try_get_matches_from(vec!["prog", "NotANumber"]);
165     /// assert!(result.is_err());
166     /// assert_eq!(result.unwrap_err().kind(), ErrorKind::ValueValidation);
167     /// ```
168     ValueValidation,
169 
170     /// Occurs when a user provides more values for an argument than were defined by setting
171     /// [`Arg::max_values`].
172     ///
173     /// # Examples
174     ///
175     /// ```rust
176     /// # use clap::{App, Arg, ErrorKind};
177     /// let result = App::new("prog")
178     ///     .arg(Arg::new("arg")
179     ///         .max_values(2))
180     ///     .try_get_matches_from(vec!["prog", "too", "many", "values"]);
181     /// assert!(result.is_err());
182     /// assert_eq!(result.unwrap_err().kind(), ErrorKind::TooManyValues);
183     /// ```
184     /// [`Arg::max_values`]: Arg::max_values()
185     TooManyValues,
186 
187     /// Occurs when the user provides fewer values for an argument than were defined by setting
188     /// [`Arg::min_values`].
189     ///
190     /// # Examples
191     ///
192     /// ```rust
193     /// # use clap::{App, Arg, ErrorKind};
194     /// let result = App::new("prog")
195     ///     .arg(Arg::new("some_opt")
196     ///         .long("opt")
197     ///         .min_values(3))
198     ///     .try_get_matches_from(vec!["prog", "--opt", "too", "few"]);
199     /// assert!(result.is_err());
200     /// assert_eq!(result.unwrap_err().kind(), ErrorKind::TooFewValues);
201     /// ```
202     /// [`Arg::min_values`]: Arg::min_values()
203     TooFewValues,
204 
205     /// Occurs when a user provides more occurrences for an argument than were defined by setting
206     /// [`Arg::max_occurrences`].
207     ///
208     /// # Examples
209     ///
210     /// ```rust
211     /// # use clap::{App, Arg, ErrorKind};
212     /// let result = App::new("prog")
213     ///     .arg(Arg::new("verbosity")
214     ///         .short('v')
215     ///         .max_occurrences(2))
216     ///     .try_get_matches_from(vec!["prog", "-vvv"]);
217     /// assert!(result.is_err());
218     /// assert_eq!(result.unwrap_err().kind(), ErrorKind::TooManyOccurrences);
219     /// ```
220     /// [`Arg::max_occurrences`]: Arg::max_occurrences()
221     TooManyOccurrences,
222 
223     /// Occurs when the user provides a different number of values for an argument than what's
224     /// been defined by setting [`Arg::number_of_values`] or than was implicitly set by
225     /// [`Arg::value_names`].
226     ///
227     /// # Examples
228     ///
229     /// ```rust
230     /// # use clap::{App, Arg, ErrorKind};
231     /// let result = App::new("prog")
232     ///     .arg(Arg::new("some_opt")
233     ///         .long("opt")
234     ///         .takes_value(true)
235     ///         .number_of_values(2))
236     ///     .try_get_matches_from(vec!["prog", "--opt", "wrong"]);
237     /// assert!(result.is_err());
238     /// assert_eq!(result.unwrap_err().kind(), ErrorKind::WrongNumberOfValues);
239     /// ```
240     ///
241     /// [`Arg::number_of_values`]: Arg::number_of_values()
242     /// [`Arg::value_names`]: Arg::value_names()
243     WrongNumberOfValues,
244 
245     /// Occurs when the user provides two values which conflict with each other and can't be used
246     /// together.
247     ///
248     /// # Examples
249     ///
250     /// ```rust
251     /// # use clap::{App, Arg, ErrorKind};
252     /// let result = App::new("prog")
253     ///     .arg(Arg::new("debug")
254     ///         .long("debug")
255     ///         .conflicts_with("color"))
256     ///     .arg(Arg::new("color")
257     ///         .long("color"))
258     ///     .try_get_matches_from(vec!["prog", "--debug", "--color"]);
259     /// assert!(result.is_err());
260     /// assert_eq!(result.unwrap_err().kind(), ErrorKind::ArgumentConflict);
261     /// ```
262     ArgumentConflict,
263 
264     /// Occurs when the user does not provide one or more required arguments.
265     ///
266     /// # Examples
267     ///
268     /// ```rust
269     /// # use clap::{App, Arg, ErrorKind};
270     /// let result = App::new("prog")
271     ///     .arg(Arg::new("debug")
272     ///         .required(true))
273     ///     .try_get_matches_from(vec!["prog"]);
274     /// assert!(result.is_err());
275     /// assert_eq!(result.unwrap_err().kind(), ErrorKind::MissingRequiredArgument);
276     /// ```
277     MissingRequiredArgument,
278 
279     /// Occurs when a subcommand is required (as defined by [`AppSettings::SubcommandRequired`]),
280     /// but the user does not provide one.
281     ///
282     /// # Examples
283     ///
284     /// ```rust
285     /// # use clap::{App, AppSettings, ErrorKind};
286     /// let err = App::new("prog")
287     ///     .setting(AppSettings::SubcommandRequired)
288     ///     .subcommand(App::new("test"))
289     ///     .try_get_matches_from(vec![
290     ///         "myprog",
291     ///     ]);
292     /// assert!(err.is_err());
293     /// assert_eq!(err.unwrap_err().kind(), ErrorKind::MissingSubcommand);
294     /// # ;
295     /// ```
296     ///
297     /// [`AppSettings::SubcommandRequired`]: crate::AppSettings::SubcommandRequired
298     MissingSubcommand,
299 
300     /// Occurs when the user provides multiple values to an argument which doesn't allow that.
301     ///
302     /// # Examples
303     ///
304     /// ```rust
305     /// # use clap::{App, Arg, ErrorKind};
306     /// let result = App::new("prog")
307     ///     .arg(Arg::new("debug")
308     ///         .long("debug")
309     ///         .multiple_occurrences(false))
310     ///     .try_get_matches_from(vec!["prog", "--debug", "--debug"]);
311     /// assert!(result.is_err());
312     /// assert_eq!(result.unwrap_err().kind(), ErrorKind::UnexpectedMultipleUsage);
313     /// ```
314     UnexpectedMultipleUsage,
315 
316     /// Occurs when the user provides a value containing invalid UTF-8.
317     ///
318     /// To allow arbitrary data
319     /// - Set [`Arg::allow_invalid_utf8`] for argument values
320     /// - Set [`AppSettings::AllowInvalidUtf8ForExternalSubcommands`] for external-subcommand
321     ///   values
322     ///
323     /// # Platform Specific
324     ///
325     /// Non-Windows platforms only (such as Linux, Unix, OSX, etc.)
326     ///
327     /// # Examples
328     ///
329     #[cfg_attr(not(unix), doc = " ```ignore")]
330     #[cfg_attr(unix, doc = " ```")]
331     /// # use clap::{App, Arg, ErrorKind, AppSettings};
332     /// # use std::os::unix::ffi::OsStringExt;
333     /// # use std::ffi::OsString;
334     /// let result = App::new("prog")
335     ///     .arg(Arg::new("utf8")
336     ///         .short('u')
337     ///         .takes_value(true))
338     ///     .try_get_matches_from(vec![OsString::from("myprog"),
339     ///                                 OsString::from("-u"),
340     ///                                 OsString::from_vec(vec![0xE9])]);
341     /// assert!(result.is_err());
342     /// assert_eq!(result.unwrap_err().kind(), ErrorKind::InvalidUtf8);
343     /// ```
344     ///
345     /// [`Arg::allow_invalid_utf8`]: crate::Arg::allow_invalid_utf8
346     /// [`AppSettings::AllowInvalidUtf8ForExternalSubcommands`]: crate::AppSettings::AllowInvalidUtf8ForExternalSubcommands
347     InvalidUtf8,
348 
349     /// Not a true "error" as it means `--help` or similar was used.
350     /// The help message will be sent to `stdout`.
351     ///
352     /// **Note**: If the help is displayed due to an error (such as missing subcommands) it will
353     /// be sent to `stderr` instead of `stdout`.
354     ///
355     /// # Examples
356     ///
357     /// ```rust
358     /// # use clap::{App, Arg, ErrorKind};
359     /// let result = App::new("prog")
360     ///     .try_get_matches_from(vec!["prog", "--help"]);
361     /// assert!(result.is_err());
362     /// assert_eq!(result.unwrap_err().kind(), ErrorKind::DisplayHelp);
363     /// ```
364     DisplayHelp,
365 
366     /// Occurs when either an argument or a [`Subcommand`] is required, as defined by
367     /// [`AppSettings::ArgRequiredElseHelp`] and
368     /// [`AppSettings::SubcommandRequiredElseHelp`], but the user did not provide
369     /// one.
370     ///
371     /// # Examples
372     ///
373     /// ```rust
374     /// # use clap::{App, Arg, AppSettings, ErrorKind, };
375     /// let result = App::new("prog")
376     ///     .setting(AppSettings::ArgRequiredElseHelp)
377     ///     .subcommand(App::new("config")
378     ///         .about("Used for configuration")
379     ///         .arg(Arg::new("config_file")
380     ///             .help("The configuration file to use")))
381     ///     .try_get_matches_from(vec!["prog"]);
382     /// assert!(result.is_err());
383     /// assert_eq!(result.unwrap_err().kind(), ErrorKind::DisplayHelpOnMissingArgumentOrSubcommand);
384     /// ```
385     ///
386     /// [`Subcommand`]: crate::Subcommand
387     /// [`AppSettings::ArgRequiredElseHelp`]: crate::AppSettings::ArgRequiredElseHelp
388     /// [`AppSettings::SubcommandRequiredElseHelp`]: crate::AppSettings::SubcommandRequiredElseHelp
389     DisplayHelpOnMissingArgumentOrSubcommand,
390 
391     /// Not a true "error" as it means `--version` or similar was used.
392     /// The message will be sent to `stdout`.
393     ///
394     /// # Examples
395     ///
396     /// ```rust
397     /// # use clap::{App, Arg, ErrorKind};
398     /// let result = App::new("prog")
399     ///     .version("3.0")
400     ///     .try_get_matches_from(vec!["prog", "--version"]);
401     /// assert!(result.is_err());
402     /// assert_eq!(result.unwrap_err().kind(), ErrorKind::DisplayVersion);
403     /// ```
404     DisplayVersion,
405 
406     /// Occurs when using the [`ArgMatches::value_of_t`] and friends to convert an argument value
407     /// into type `T`, but the argument you requested wasn't used. I.e. you asked for an argument
408     /// with name `config` to be converted, but `config` wasn't used by the user.
409     ///
410     /// [`ArgMatches::value_of_t`]: crate::ArgMatches::value_of_t()
411     ArgumentNotFound,
412 
413     /// Represents an [I/O error].
414     /// Can occur when writing to `stderr` or `stdout` or reading a configuration file.
415     ///
416     /// [I/O error]: std::io::Error
417     Io,
418 
419     /// Represents a [Format error] (which is a part of [`Display`]).
420     /// Typically caused by writing to `stderr` or `stdout`.
421     ///
422     /// [`Display`]: std::fmt::Display
423     /// [Format error]: std::fmt::Error
424     Format,
425 }
426 
427 /// Command Line Argument Parser Error
428 ///
429 /// See [`App::error`] to create an error.
430 ///
431 /// [`App::error`]: crate::App::error
432 #[derive(Debug)]
433 pub struct Error {
434     /// Formatted error message, enhancing the cause message with extra information
435     message: Message,
436     /// The type of error
437     pub kind: ErrorKind,
438     /// Additional information depending on the error kind, like values and argument names.
439     /// Useful when you want to render an error of your own.
440     pub info: Vec<String>,
441     source: Option<Box<dyn error::Error + Send + Sync>>,
442     wait_on_exit: bool,
443     backtrace: Option<Backtrace>,
444 }
445 
446 impl Error {
447     /// Create an unformatted error
448     ///
449     /// This is for you need to pass the error up to
450     /// a place that has access to the `App` at which point you can call [`Error::format`].
451     ///
452     /// Prefer [`App::error`] for generating errors.
453     ///
454     /// [`App::error`]: crate::App::error
raw(kind: ErrorKind, message: impl std::fmt::Display) -> Self455     pub fn raw(kind: ErrorKind, message: impl std::fmt::Display) -> Self {
456         Self::new(message.to_string(), kind, false)
457     }
458 
459     /// Format the existing message with the App's context
460     #[must_use]
format(mut self, app: &mut App) -> Self461     pub fn format(mut self, app: &mut App) -> Self {
462         app._build();
463         let usage = app.render_usage();
464         self.message.format(app, usage);
465         self.wait_on_exit = app.settings.is_set(AppSettings::WaitOnError);
466         self
467     }
468 
469     /// Type of error for programmatic processing
kind(&self) -> ErrorKind470     pub fn kind(&self) -> ErrorKind {
471         self.kind
472     }
473 
474     /// Should the message be written to `stdout` or not?
475     #[inline]
use_stderr(&self) -> bool476     pub fn use_stderr(&self) -> bool {
477         !matches!(
478             self.kind(),
479             ErrorKind::DisplayHelp | ErrorKind::DisplayVersion
480         )
481     }
482 
483     /// Prints the error and exits.
484     ///
485     /// Depending on the error kind, this either prints to `stderr` and exits with a status of `2`
486     /// or prints to `stdout` and exits with a status of `0`.
exit(&self) -> !487     pub fn exit(&self) -> ! {
488         if self.use_stderr() {
489             // Swallow broken pipe errors
490             let _ = self.print();
491 
492             if self.wait_on_exit {
493                 wlnerr!("\nPress [ENTER] / [RETURN] to continue...");
494                 let mut s = String::new();
495                 let i = io::stdin();
496                 i.lock().read_line(&mut s).unwrap();
497             }
498 
499             safe_exit(USAGE_CODE);
500         }
501 
502         // Swallow broken pipe errors
503         let _ = self.print();
504         safe_exit(SUCCESS_CODE)
505     }
506 
507     /// Prints formatted and colored error to `stdout` or `stderr` according to its error kind
508     ///
509     /// # Example
510     /// ```no_run
511     /// use clap::App;
512     ///
513     /// match App::new("App").try_get_matches() {
514     ///     Ok(matches) => {
515     ///         // do_something
516     ///     },
517     ///     Err(err) => {
518     ///         err.print().expect("Error writing Error");
519     ///         // do_something
520     ///     },
521     /// };
522     /// ```
print(&self) -> io::Result<()>523     pub fn print(&self) -> io::Result<()> {
524         self.message.formatted().print()
525     }
526 
527     /// Deprecated, replaced with [`App::error`]
528     ///
529     /// [`App::error`]: crate::App::error
530     #[deprecated(since = "3.0.0", note = "Replaced with `App::error`")]
with_description(description: String, kind: ErrorKind) -> Self531     pub fn with_description(description: String, kind: ErrorKind) -> Self {
532         Error::raw(kind, description)
533     }
534 
new(message: impl Into<Message>, kind: ErrorKind, wait_on_exit: bool) -> Self535     pub(crate) fn new(message: impl Into<Message>, kind: ErrorKind, wait_on_exit: bool) -> Self {
536         Self {
537             message: message.into(),
538             kind,
539             info: vec![],
540             source: None,
541             wait_on_exit,
542             backtrace: Backtrace::new(),
543         }
544     }
545 
546     #[inline(never)]
for_app( app: &App, colorizer: Colorizer, kind: ErrorKind, info: Vec<String>, ) -> Self547     pub(crate) fn for_app(
548         app: &App,
549         colorizer: Colorizer,
550         kind: ErrorKind,
551         info: Vec<String>,
552     ) -> Self {
553         Self::new(
554             colorizer,
555             kind,
556             app.settings.is_set(AppSettings::WaitOnError),
557         )
558         .set_info(info)
559     }
560 
set_info(mut self, info: Vec<String>) -> Self561     pub(crate) fn set_info(mut self, info: Vec<String>) -> Self {
562         self.info = info;
563         self
564     }
565 
set_source(mut self, source: Box<dyn error::Error + Send + Sync>) -> Self566     pub(crate) fn set_source(mut self, source: Box<dyn error::Error + Send + Sync>) -> Self {
567         self.source = Some(source);
568         self
569     }
570 
argument_conflict( app: &App, arg: &Arg, others: Vec<String>, usage: String, ) -> Self571     pub(crate) fn argument_conflict(
572         app: &App,
573         arg: &Arg,
574         others: Vec<String>,
575         usage: String,
576     ) -> Self {
577         let mut c = Colorizer::new(true, app.get_color());
578         let arg = arg.to_string();
579 
580         start_error(&mut c, "The argument '");
581         c.warning(arg);
582         c.none("' cannot be used with");
583 
584         match others.len() {
585             0 => {
586                 c.none(" one or more of the other specified arguments");
587             }
588             1 => {
589                 c.none(" '");
590                 c.warning(&*others[0]);
591                 c.none("'");
592             }
593             _ => {
594                 c.none(":");
595                 for v in &others {
596                     c.none("\n    ");
597                     c.warning(&**v);
598                 }
599             }
600         }
601 
602         put_usage(&mut c, usage);
603         try_help(app, &mut c);
604 
605         Self::for_app(app, c, ErrorKind::ArgumentConflict, others)
606     }
607 
empty_value(app: &App, arg: &Arg, usage: String) -> Self608     pub(crate) fn empty_value(app: &App, arg: &Arg, usage: String) -> Self {
609         let mut c = Colorizer::new(true, app.get_color());
610         let arg = arg.to_string();
611 
612         start_error(&mut c, "The argument '");
613         c.warning(&*arg);
614         c.none("' requires a value but none was supplied");
615         put_usage(&mut c, usage);
616         try_help(app, &mut c);
617 
618         Self::for_app(app, c, ErrorKind::EmptyValue, vec![arg])
619     }
620 
no_equals(app: &App, arg: String, usage: String) -> Self621     pub(crate) fn no_equals(app: &App, arg: String, usage: String) -> Self {
622         let mut c = Colorizer::new(true, app.get_color());
623 
624         start_error(&mut c, "Equal sign is needed when assigning values to '");
625         c.warning(&*arg);
626         c.none("'.");
627 
628         put_usage(&mut c, usage);
629         try_help(app, &mut c);
630 
631         Self::for_app(app, c, ErrorKind::NoEquals, vec![arg])
632     }
633 
invalid_value( app: &App, bad_val: String, good_vals: &[&str], arg: &Arg, usage: String, ) -> Self634     pub(crate) fn invalid_value(
635         app: &App,
636         bad_val: String,
637         good_vals: &[&str],
638         arg: &Arg,
639         usage: String,
640     ) -> Self {
641         let mut c = Colorizer::new(true, app.get_color());
642         let suffix = suggestions::did_you_mean(&bad_val, good_vals.iter()).pop();
643         let arg = arg.to_string();
644 
645         let mut sorted: Vec<String> = good_vals
646             .iter()
647             .map(|&v| {
648                 if v.contains(char::is_whitespace) {
649                     format!("{:?}", v)
650                 } else {
651                     v.to_owned()
652                 }
653             })
654             .collect();
655         sorted.sort();
656 
657         start_error(&mut c, "");
658         c.warning(format!("{:?}", bad_val));
659         c.none(" isn't a valid value for '");
660         c.warning(&*arg);
661         c.none("'\n\t[possible values: ");
662 
663         if let Some((last, elements)) = sorted.split_last() {
664             for v in elements {
665                 c.good(v);
666                 c.none(", ");
667             }
668 
669             c.good(last);
670         }
671 
672         c.none("]");
673 
674         if let Some(val) = suffix {
675             c.none("\n\n\tDid you mean ");
676             c.good(format!("{:?}", val));
677             c.none("?");
678         }
679 
680         put_usage(&mut c, usage);
681         try_help(app, &mut c);
682 
683         let mut info = vec![arg, bad_val];
684         info.extend(sorted);
685 
686         Self::for_app(app, c, ErrorKind::InvalidValue, info)
687     }
688 
invalid_subcommand( app: &App, subcmd: String, did_you_mean: String, name: String, usage: String, ) -> Self689     pub(crate) fn invalid_subcommand(
690         app: &App,
691         subcmd: String,
692         did_you_mean: String,
693         name: String,
694         usage: String,
695     ) -> Self {
696         let mut c = Colorizer::new(true, app.get_color());
697 
698         start_error(&mut c, "The subcommand '");
699         c.warning(&*subcmd);
700         c.none("' wasn't recognized\n\n\tDid you mean ");
701         c.good(did_you_mean);
702         c.none("");
703         c.none(format!(
704             "?\n\nIf you believe you received this message in error, try re-running with '{} ",
705             name
706         ));
707         c.good("--");
708         c.none(format!(" {}'", subcmd));
709         put_usage(&mut c, usage);
710         try_help(app, &mut c);
711 
712         Self::for_app(app, c, ErrorKind::InvalidSubcommand, vec![subcmd])
713     }
714 
unrecognized_subcommand(app: &App, subcmd: String, name: String) -> Self715     pub(crate) fn unrecognized_subcommand(app: &App, subcmd: String, name: String) -> Self {
716         let mut c = Colorizer::new(true, app.get_color());
717 
718         start_error(&mut c, " The subcommand '");
719         c.warning(&*subcmd);
720         c.none("' wasn't recognized\n\n");
721         c.warning("USAGE:");
722         c.none(format!("\n    {} <subcommands>", name));
723         try_help(app, &mut c);
724 
725         Self::for_app(app, c, ErrorKind::UnrecognizedSubcommand, vec![subcmd])
726     }
727 
missing_required_argument( app: &App, required: Vec<String>, usage: String, ) -> Self728     pub(crate) fn missing_required_argument(
729         app: &App,
730         required: Vec<String>,
731         usage: String,
732     ) -> Self {
733         let mut c = Colorizer::new(true, app.get_color());
734 
735         start_error(
736             &mut c,
737             "The following required arguments were not provided:",
738         );
739 
740         for v in &required {
741             c.none("\n    ");
742             c.good(&**v);
743         }
744 
745         put_usage(&mut c, usage);
746         try_help(app, &mut c);
747 
748         Self::for_app(app, c, ErrorKind::MissingRequiredArgument, required)
749     }
750 
missing_subcommand(app: &App, name: String, usage: String) -> Self751     pub(crate) fn missing_subcommand(app: &App, name: String, usage: String) -> Self {
752         let mut c = Colorizer::new(true, app.get_color());
753 
754         start_error(&mut c, "'");
755         c.warning(name);
756         c.none("' requires a subcommand, but one was not provided");
757         put_usage(&mut c, usage);
758         try_help(app, &mut c);
759 
760         Self::for_app(app, c, ErrorKind::MissingSubcommand, vec![])
761     }
762 
invalid_utf8(app: &App, usage: String) -> Self763     pub(crate) fn invalid_utf8(app: &App, usage: String) -> Self {
764         let mut c = Colorizer::new(true, app.get_color());
765 
766         start_error(
767             &mut c,
768             "Invalid UTF-8 was detected in one or more arguments",
769         );
770         put_usage(&mut c, usage);
771         try_help(app, &mut c);
772 
773         Self::for_app(app, c, ErrorKind::InvalidUtf8, vec![])
774     }
775 
too_many_occurrences( app: &App, arg: &Arg, max_occurs: usize, curr_occurs: usize, usage: String, ) -> Self776     pub(crate) fn too_many_occurrences(
777         app: &App,
778         arg: &Arg,
779         max_occurs: usize,
780         curr_occurs: usize,
781         usage: String,
782     ) -> Self {
783         let mut c = Colorizer::new(true, app.get_color());
784         let were_provided = Error::singular_or_plural(curr_occurs);
785         let arg = arg.to_string();
786         let max_occurs = max_occurs.to_string();
787         let curr_occurs = curr_occurs.to_string();
788 
789         start_error(&mut c, "The argument '");
790         c.warning(&*arg);
791         c.none("' allows at most ");
792         c.warning(&*max_occurs);
793         c.none(" occurrences, but ");
794         c.warning(&*curr_occurs);
795         c.none(were_provided);
796         put_usage(&mut c, usage);
797         try_help(app, &mut c);
798 
799         Self::for_app(
800             app,
801             c,
802             ErrorKind::TooManyOccurrences,
803             vec![arg, curr_occurs, max_occurs],
804         )
805     }
806 
too_many_values(app: &App, val: String, arg: String, usage: String) -> Self807     pub(crate) fn too_many_values(app: &App, val: String, arg: String, usage: String) -> Self {
808         let mut c = Colorizer::new(true, app.get_color());
809 
810         start_error(&mut c, "The value '");
811         c.warning(&*val);
812         c.none("' was provided to '");
813         c.warning(&*arg);
814         c.none("' but it wasn't expecting any more values");
815         put_usage(&mut c, usage);
816         try_help(app, &mut c);
817 
818         Self::for_app(app, c, ErrorKind::TooManyValues, vec![arg, val])
819     }
820 
too_few_values( app: &App, arg: &Arg, min_vals: usize, curr_vals: usize, usage: String, ) -> Self821     pub(crate) fn too_few_values(
822         app: &App,
823         arg: &Arg,
824         min_vals: usize,
825         curr_vals: usize,
826         usage: String,
827     ) -> Self {
828         let mut c = Colorizer::new(true, app.get_color());
829         let were_provided = Error::singular_or_plural(curr_vals);
830         let arg = arg.to_string();
831         let min_vals = min_vals.to_string();
832         let curr_vals = curr_vals.to_string();
833 
834         start_error(&mut c, "The argument '");
835         c.warning(&*arg);
836         c.none("' requires at least ");
837         c.warning(&*min_vals);
838         c.none(" values, but only ");
839         c.warning(&*curr_vals);
840         c.none(were_provided);
841         put_usage(&mut c, usage);
842         try_help(app, &mut c);
843 
844         Self::for_app(
845             app,
846             c,
847             ErrorKind::TooFewValues,
848             vec![arg, curr_vals, min_vals],
849         )
850     }
851 
value_validation( app: &App, arg: String, val: String, err: Box<dyn error::Error + Send + Sync>, ) -> Self852     pub(crate) fn value_validation(
853         app: &App,
854         arg: String,
855         val: String,
856         err: Box<dyn error::Error + Send + Sync>,
857     ) -> Self {
858         let mut err = Self::value_validation_with_color(
859             arg,
860             val,
861             err,
862             app.get_color(),
863             app.settings.is_set(AppSettings::WaitOnError),
864         );
865         match &mut err.message {
866             Message::Raw(_) => {
867                 unreachable!("`value_validation_with_color` only deals in formatted errors")
868             }
869             Message::Formatted(c) => try_help(app, c),
870         }
871         err
872     }
873 
value_validation_without_app( arg: String, val: String, err: Box<dyn error::Error + Send + Sync>, ) -> Self874     pub(crate) fn value_validation_without_app(
875         arg: String,
876         val: String,
877         err: Box<dyn error::Error + Send + Sync>,
878     ) -> Self {
879         let mut err = Self::value_validation_with_color(arg, val, err, ColorChoice::Never, false);
880         match &mut err.message {
881             Message::Raw(_) => {
882                 unreachable!("`value_validation_with_color` only deals in formatted errors")
883             }
884             Message::Formatted(c) => {
885                 c.none("\n");
886             }
887         }
888         err
889     }
890 
value_validation_with_color( arg: String, val: String, err: Box<dyn error::Error + Send + Sync>, color: ColorChoice, wait_on_exit: bool, ) -> Self891     fn value_validation_with_color(
892         arg: String,
893         val: String,
894         err: Box<dyn error::Error + Send + Sync>,
895         color: ColorChoice,
896         wait_on_exit: bool,
897     ) -> Self {
898         let mut c = Colorizer::new(true, color);
899 
900         start_error(&mut c, "Invalid value");
901 
902         c.none(" for '");
903         c.warning(&*arg);
904         c.none("'");
905 
906         c.none(format!(": {}", err));
907 
908         Self::new(c, ErrorKind::ValueValidation, wait_on_exit)
909             .set_info(vec![arg, val, err.to_string()])
910             .set_source(err)
911     }
912 
wrong_number_of_values( app: &App, arg: &Arg, num_vals: usize, curr_vals: usize, usage: String, ) -> Self913     pub(crate) fn wrong_number_of_values(
914         app: &App,
915         arg: &Arg,
916         num_vals: usize,
917         curr_vals: usize,
918         usage: String,
919     ) -> Self {
920         let mut c = Colorizer::new(true, app.get_color());
921         let were_provided = Error::singular_or_plural(curr_vals);
922         let arg = arg.to_string();
923         let num_vals = num_vals.to_string();
924         let curr_vals = curr_vals.to_string();
925 
926         start_error(&mut c, "The argument '");
927         c.warning(&*arg);
928         c.none("' requires ");
929         c.warning(&*num_vals);
930         c.none(" values, but ");
931         c.warning(&*curr_vals);
932         c.none(were_provided);
933         put_usage(&mut c, usage);
934         try_help(app, &mut c);
935 
936         Self::for_app(
937             app,
938             c,
939             ErrorKind::WrongNumberOfValues,
940             vec![arg, curr_vals, num_vals],
941         )
942     }
943 
unexpected_multiple_usage(app: &App, arg: &Arg, usage: String) -> Self944     pub(crate) fn unexpected_multiple_usage(app: &App, arg: &Arg, usage: String) -> Self {
945         let mut c = Colorizer::new(true, app.get_color());
946         let arg = arg.to_string();
947 
948         start_error(&mut c, "The argument '");
949         c.warning(&*arg);
950         c.none("' was provided more than once, but cannot be used multiple times");
951         put_usage(&mut c, usage);
952         try_help(app, &mut c);
953 
954         Self::for_app(app, c, ErrorKind::UnexpectedMultipleUsage, vec![arg])
955     }
956 
unknown_argument( app: &App, arg: String, did_you_mean: Option<(String, Option<String>)>, usage: String, ) -> Self957     pub(crate) fn unknown_argument(
958         app: &App,
959         arg: String,
960         did_you_mean: Option<(String, Option<String>)>,
961         usage: String,
962     ) -> Self {
963         let mut c = Colorizer::new(true, app.get_color());
964 
965         start_error(&mut c, "Found argument '");
966         c.warning(&*arg);
967         c.none("' which wasn't expected, or isn't valid in this context");
968 
969         if let Some((flag, subcmd)) = did_you_mean {
970             let flag = format!("--{}", flag);
971             c.none("\n\n\tDid you mean ");
972 
973             if let Some(subcmd) = subcmd {
974                 c.none("to put '");
975                 c.good(flag);
976                 c.none("' after the subcommand '");
977                 c.good(subcmd);
978                 c.none("'?");
979             } else {
980                 c.none("'");
981                 c.good(flag);
982                 c.none("'?");
983             }
984         }
985 
986         // If the user wants to supply things like `--a-flag` or `-b` as a value,
987         // suggest `--` for disambiguation.
988         if arg.starts_with('-') {
989             c.none(format!(
990                 "\n\n\tIf you tried to supply `{}` as a value rather than a flag, use `-- {}`",
991                 arg, arg
992             ));
993         }
994 
995         put_usage(&mut c, usage);
996         try_help(app, &mut c);
997 
998         Self::for_app(app, c, ErrorKind::UnknownArgument, vec![arg])
999     }
1000 
unnecessary_double_dash(app: &App, arg: String, usage: String) -> Self1001     pub(crate) fn unnecessary_double_dash(app: &App, arg: String, usage: String) -> Self {
1002         let mut c = Colorizer::new(true, app.get_color());
1003 
1004         start_error(&mut c, "Found argument '");
1005         c.warning(&*arg);
1006         c.none("' which wasn't expected, or isn't valid in this context");
1007 
1008         c.none(format!(
1009             "\n\n\tIf you tried to supply `{}` as a subcommand, remove the '--' before it.",
1010             arg
1011         ));
1012         put_usage(&mut c, usage);
1013         try_help(app, &mut c);
1014 
1015         Self::for_app(app, c, ErrorKind::UnknownArgument, vec![arg])
1016     }
1017 
argument_not_found_auto(arg: String) -> Self1018     pub(crate) fn argument_not_found_auto(arg: String) -> Self {
1019         let mut c = Colorizer::new(true, ColorChoice::Never);
1020 
1021         start_error(&mut c, "The argument '");
1022         c.warning(&*arg);
1023         c.none("' wasn't found\n");
1024 
1025         Self::new(c, ErrorKind::ArgumentNotFound, false).set_info(vec![arg])
1026     }
1027 
1028     /// Returns the singular or plural form on the verb to be based on the argument's value.
singular_or_plural(n: usize) -> &'static str1029     fn singular_or_plural(n: usize) -> &'static str {
1030         if n > 1 {
1031             " were provided"
1032         } else {
1033             " was provided"
1034         }
1035     }
1036 }
1037 
1038 impl From<io::Error> for Error {
from(e: io::Error) -> Self1039     fn from(e: io::Error) -> Self {
1040         Error::raw(ErrorKind::Io, e)
1041     }
1042 }
1043 
1044 impl From<fmt::Error> for Error {
from(e: fmt::Error) -> Self1045     fn from(e: fmt::Error) -> Self {
1046         Error::raw(ErrorKind::Format, e)
1047     }
1048 }
1049 
1050 impl error::Error for Error {
1051     #[allow(trivial_casts)]
source(&self) -> Option<&(dyn error::Error + 'static)>1052     fn source(&self) -> Option<&(dyn error::Error + 'static)> {
1053         self.source.as_ref().map(|e| e.as_ref() as _)
1054     }
1055 }
1056 
1057 impl Display for Error {
fmt(&self, f: &mut Formatter) -> fmt::Result1058     fn fmt(&self, f: &mut Formatter) -> fmt::Result {
1059         // Assuming `self.message` already has a trailing newline, from `try_help` or similar
1060         write!(f, "{}", self.message.formatted())?;
1061         if let Some(backtrace) = self.backtrace.as_ref() {
1062             writeln!(f)?;
1063             writeln!(f, "Backtrace:")?;
1064             writeln!(f, "{}", backtrace)?;
1065         }
1066         Ok(())
1067     }
1068 }
1069 
start_error(c: &mut Colorizer, msg: impl Into<String>)1070 fn start_error(c: &mut Colorizer, msg: impl Into<String>) {
1071     c.error("error:");
1072     c.none(" ");
1073     c.none(msg);
1074 }
1075 
put_usage(c: &mut Colorizer, usage: impl Into<String>)1076 fn put_usage(c: &mut Colorizer, usage: impl Into<String>) {
1077     c.none("\n\n");
1078     c.none(usage);
1079 }
1080 
try_help(app: &App, c: &mut Colorizer)1081 fn try_help(app: &App, c: &mut Colorizer) {
1082     if !app.settings.is_set(AppSettings::DisableHelpFlag) {
1083         c.none("\n\nFor more information try ");
1084         c.good("--help");
1085         c.none("\n");
1086     } else if app.has_subcommands() && !app.settings.is_set(AppSettings::DisableHelpSubcommand) {
1087         c.none("\n\nFor more information try ");
1088         c.good("help");
1089         c.none("\n");
1090     } else {
1091         c.none("\n");
1092     }
1093 }
1094 
1095 #[derive(Clone, Debug)]
1096 pub(crate) enum Message {
1097     Raw(String),
1098     Formatted(Colorizer),
1099 }
1100 
1101 impl Message {
format(&mut self, app: &App, usage: String)1102     fn format(&mut self, app: &App, usage: String) {
1103         match self {
1104             Message::Raw(s) => {
1105                 let mut c = Colorizer::new(true, app.get_color());
1106 
1107                 let mut message = String::new();
1108                 std::mem::swap(s, &mut message);
1109                 start_error(&mut c, message);
1110                 put_usage(&mut c, usage);
1111                 try_help(app, &mut c);
1112                 *self = Self::Formatted(c);
1113             }
1114             Message::Formatted(_) => {}
1115         }
1116     }
1117 
formatted(&self) -> Cow<Colorizer>1118     fn formatted(&self) -> Cow<Colorizer> {
1119         match self {
1120             Message::Raw(s) => {
1121                 let mut c = Colorizer::new(true, ColorChoice::Never);
1122                 start_error(&mut c, s);
1123                 Cow::Owned(c)
1124             }
1125             Message::Formatted(c) => Cow::Borrowed(c),
1126         }
1127     }
1128 }
1129 
1130 impl From<String> for Message {
from(inner: String) -> Self1131     fn from(inner: String) -> Self {
1132         Self::Raw(inner)
1133     }
1134 }
1135 
1136 impl From<Colorizer> for Message {
from(inner: Colorizer) -> Self1137     fn from(inner: Colorizer) -> Self {
1138         Self::Formatted(inner)
1139     }
1140 }
1141 
1142 #[cfg(feature = "debug")]
1143 #[derive(Debug)]
1144 struct Backtrace(backtrace::Backtrace);
1145 
1146 #[cfg(feature = "debug")]
1147 impl Backtrace {
new() -> Option<Self>1148     fn new() -> Option<Self> {
1149         Some(Self(backtrace::Backtrace::new()))
1150     }
1151 }
1152 
1153 #[cfg(feature = "debug")]
1154 impl Display for Backtrace {
fmt(&self, f: &mut Formatter) -> fmt::Result1155     fn fmt(&self, f: &mut Formatter) -> fmt::Result {
1156         // `backtrace::Backtrace` uses `Debug` instead of `Display`
1157         write!(f, "{:?}", self.0)
1158     }
1159 }
1160 
1161 #[cfg(not(feature = "debug"))]
1162 #[derive(Debug)]
1163 struct Backtrace;
1164 
1165 #[cfg(not(feature = "debug"))]
1166 impl Backtrace {
new() -> Option<Self>1167     fn new() -> Option<Self> {
1168         None
1169     }
1170 }
1171 
1172 #[cfg(not(feature = "debug"))]
1173 impl Display for Backtrace {
fmt(&self, _: &mut Formatter) -> fmt::Result1174     fn fmt(&self, _: &mut Formatter) -> fmt::Result {
1175         Ok(())
1176     }
1177 }
1178 
1179 #[cfg(test)]
1180 mod tests {
1181     /// Check `clap::Error` impls Send and Sync.
1182     mod clap_error_impl_send_sync {
1183         use crate::Error;
1184         trait Foo: std::error::Error + Send + Sync + 'static {}
1185         impl Foo for Error {}
1186     }
1187 }
1188