rust/rhg/src/error.rs
author Simon Sapin <simon.sapin@octobus.net>
Mon, 08 Feb 2021 21:37:30 +0100
changeset 46503 d8730ff51d5a
parent 46499 eace48b4a786
child 46591 21d3b40b4c0e
permissions -rw-r--r--
rhg: Add support for -R and --repository command-line arguments Differential Revision: https://phab.mercurial-scm.org/D9970
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
46436
252d1bdba33d rhg: replace `map_*_error` functions with `From` impls
Simon Sapin <simon.sapin@octobus.net>
parents: 46435
diff changeset
     1
use crate::ui::utf8_to_local;
45049
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 44982
diff changeset
     2
use crate::ui::UiError;
46446
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46445
diff changeset
     3
use format_bytes::format_bytes;
46484
a6e4e4650bac rhg: Parse system and user configuration at program start
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
     4
use hg::config::{ConfigError, ConfigParseError};
46446
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46445
diff changeset
     5
use hg::errors::HgError;
46486
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
     6
use hg::repo::RepoError;
46437
b274aa2f20fd rust: remove three enums that were identical to `RevlogError`
Simon Sapin <simon.sapin@octobus.net>
parents: 46436
diff changeset
     7
use hg::revlog::revlog::RevlogError;
46446
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46445
diff changeset
     8
use hg::utils::files::get_bytes_from_path;
45049
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 44982
diff changeset
     9
use std::convert::From;
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 44982
diff changeset
    10
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 44982
diff changeset
    11
/// The kind of command error
46445
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    12
#[derive(Debug)]
46434
3e2d539d0d1a rust: remove `FooError` structs with only `kind: FooErrorKind` enum field
Simon Sapin <simon.sapin@octobus.net>
parents: 45984
diff changeset
    13
pub enum CommandError {
46445
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    14
    /// Exit with an error message and "standard" failure exit code.
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    15
    Abort { message: Vec<u8> },
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    16
45542
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45439
diff changeset
    17
    /// A mercurial capability as not been implemented.
46445
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    18
    ///
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    19
    /// There is no error message printed in this case.
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    20
    /// Instead, we exit with a specic status code and a wrapper script may
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    21
    /// fallback to Python-based Mercurial.
45542
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45439
diff changeset
    22
    Unimplemented,
45049
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 44982
diff changeset
    23
}
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 44982
diff changeset
    24
46434
3e2d539d0d1a rust: remove `FooError` structs with only `kind: FooErrorKind` enum field
Simon Sapin <simon.sapin@octobus.net>
parents: 45984
diff changeset
    25
impl CommandError {
46445
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    26
    pub fn abort(message: impl AsRef<str>) -> Self {
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    27
        CommandError::Abort {
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    28
            // TODO: bytes-based (instead of Unicode-based) formatting
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    29
            // of error messages to handle non-UTF-8 filenames etc:
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    30
            // https://www.mercurial-scm.org/wiki/EncodingStrategy#Mixing_output
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    31
            message: utf8_to_local(message.as_ref()).into(),
45049
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 44982
diff changeset
    32
        }
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 44982
diff changeset
    33
    }
46445
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    34
}
45361
47997afadf08 rhg: ask the error message from `CommandError`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45360
diff changeset
    35
46445
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    36
impl From<HgError> for CommandError {
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    37
    fn from(error: HgError) -> Self {
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    38
        match error {
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    39
            HgError::UnsupportedFeature(_) => CommandError::Unimplemented,
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    40
            _ => CommandError::abort(error.to_string()),
45361
47997afadf08 rhg: ask the error message from `CommandError`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45360
diff changeset
    41
        }
47997afadf08 rhg: ask the error message from `CommandError`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45360
diff changeset
    42
    }
45049
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 44982
diff changeset
    43
}
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 44982
diff changeset
    44
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 44982
diff changeset
    45
impl From<UiError> for CommandError {
46445
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    46
    fn from(_error: UiError) -> Self {
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    47
        // If we already failed writing to stdout or stderr,
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    48
        // writing an error message to stderr about it would be likely to fail
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    49
        // too.
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
    50
        CommandError::abort("")
45049
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 44982
diff changeset
    51
    }
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 44982
diff changeset
    52
}
45363
5dbf875b3275 rhg: simplify `FindRootError` handling
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45361
diff changeset
    53
46486
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
    54
impl From<RepoError> for CommandError {
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
    55
    fn from(error: RepoError) -> Self {
46446
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46445
diff changeset
    56
        match error {
46503
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46499
diff changeset
    57
            RepoError::NotFound { at } => CommandError::Abort {
46446
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46445
diff changeset
    58
                message: format_bytes!(
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46445
diff changeset
    59
                    b"no repository found in '{}' (.hg not found)!",
46503
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46499
diff changeset
    60
                    get_bytes_from_path(at)
46446
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46445
diff changeset
    61
                ),
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46445
diff changeset
    62
            },
46486
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
    63
            RepoError::ConfigParseError(error) => error.into(),
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
    64
            RepoError::Other(error) => error.into(),
45363
5dbf875b3275 rhg: simplify `FindRootError` handling
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45361
diff changeset
    65
        }
5dbf875b3275 rhg: simplify `FindRootError` handling
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45361
diff changeset
    66
    }
5dbf875b3275 rhg: simplify `FindRootError` handling
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45361
diff changeset
    67
}
46436
252d1bdba33d rhg: replace `map_*_error` functions with `From` impls
Simon Sapin <simon.sapin@octobus.net>
parents: 46435
diff changeset
    68
46484
a6e4e4650bac rhg: Parse system and user configuration at program start
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
    69
impl From<ConfigError> for CommandError {
a6e4e4650bac rhg: Parse system and user configuration at program start
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
    70
    fn from(error: ConfigError) -> Self {
a6e4e4650bac rhg: Parse system and user configuration at program start
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
    71
        match error {
46486
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
    72
            ConfigError::Parse(error) => error.into(),
46484
a6e4e4650bac rhg: Parse system and user configuration at program start
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
    73
            ConfigError::Other(error) => error.into(),
a6e4e4650bac rhg: Parse system and user configuration at program start
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
    74
        }
a6e4e4650bac rhg: Parse system and user configuration at program start
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
    75
    }
a6e4e4650bac rhg: Parse system and user configuration at program start
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
    76
}
a6e4e4650bac rhg: Parse system and user configuration at program start
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
    77
46486
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
    78
impl From<ConfigParseError> for CommandError {
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
    79
    fn from(error: ConfigParseError) -> Self {
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
    80
        let ConfigParseError {
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
    81
            origin,
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
    82
            line,
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
    83
            bytes,
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
    84
        } = error;
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
    85
        let line_message = if let Some(line_number) = line {
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
    86
            format_bytes!(b" at line {}", line_number.to_string().into_bytes())
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
    87
        } else {
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
    88
            Vec::new()
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
    89
        };
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
    90
        CommandError::Abort {
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
    91
            message: format_bytes!(
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
    92
                b"config parse error in {}{}: '{}'",
46499
eace48b4a786 rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents: 46486
diff changeset
    93
                origin,
46486
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
    94
                line_message,
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
    95
                bytes
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
    96
            ),
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
    97
        }
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
    98
    }
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
    99
}
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46484
diff changeset
   100
46437
b274aa2f20fd rust: remove three enums that were identical to `RevlogError`
Simon Sapin <simon.sapin@octobus.net>
parents: 46436
diff changeset
   101
impl From<(RevlogError, &str)> for CommandError {
b274aa2f20fd rust: remove three enums that were identical to `RevlogError`
Simon Sapin <simon.sapin@octobus.net>
parents: 46436
diff changeset
   102
    fn from((err, rev): (RevlogError, &str)) -> CommandError {
46436
252d1bdba33d rhg: replace `map_*_error` functions with `From` impls
Simon Sapin <simon.sapin@octobus.net>
parents: 46435
diff changeset
   103
        match err {
46445
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
   104
            RevlogError::InvalidRevision => CommandError::abort(format!(
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
   105
                "invalid revision identifier {}",
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
   106
                rev
46436
252d1bdba33d rhg: replace `map_*_error` functions with `From` impls
Simon Sapin <simon.sapin@octobus.net>
parents: 46435
diff changeset
   107
            )),
46445
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
   108
            RevlogError::AmbiguousPrefix => CommandError::abort(format!(
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
   109
                "ambiguous revision identifier {}",
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
   110
                rev
46436
252d1bdba33d rhg: replace `map_*_error` functions with `From` impls
Simon Sapin <simon.sapin@octobus.net>
parents: 46435
diff changeset
   111
            )),
46445
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
   112
            RevlogError::Other(error) => error.into(),
46436
252d1bdba33d rhg: replace `map_*_error` functions with `From` impls
Simon Sapin <simon.sapin@octobus.net>
parents: 46435
diff changeset
   113
        }
252d1bdba33d rhg: replace `map_*_error` functions with `From` impls
Simon Sapin <simon.sapin@octobus.net>
parents: 46435
diff changeset
   114
    }
252d1bdba33d rhg: replace `map_*_error` functions with `From` impls
Simon Sapin <simon.sapin@octobus.net>
parents: 46435
diff changeset
   115
}