Skip to main content

cargo_governor/
error.rs

1//! Error types for cargo-governor
2
3use std::process::ExitCode;
4
5/// Command exit codes matching the specification
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub enum CommandExitCode {
8    /// Success
9    Success = 0,
10    /// General error
11    GeneralError = 1,
12    /// Invalid arguments
13    InvalidArguments = 2,
14    /// Config error
15    ConfigError = 3,
16    /// Git error
17    GitError = 10,
18    /// Registry error
19    RegistryError = 11,
20    /// Version error
21    VersionError = 12,
22    /// Check failed
23    CheckFailed = 13,
24    /// Security error
25    SecurityError = 14,
26    /// Network error
27    NetworkError = 15,
28    /// Pre-publish checks failed
29    PrePublishChecksFailed = 16,
30    /// Partial success
31    PartialSuccess = 20,
32    /// Rollback failed
33    RollbackFailed = 21,
34    /// Checkpoint created
35    CheckpointCreated = 30,
36    /// No changes
37    NoChanges = 31,
38    /// Drift detected in owners
39    DriftDetected = 32,
40}
41
42impl From<CommandExitCode> for ExitCode {
43    fn from(code: CommandExitCode) -> Self {
44        Self::from(code as u8)
45    }
46}
47
48/// Result type for commands
49pub type Result<T> = std::result::Result<T, Error>;
50
51/// Main error type
52#[derive(Debug, thiserror::Error)]
53pub enum Error {
54    #[error("CLI error: {0}")]
55    Cli(String),
56
57    #[error("Config error: {0}")]
58    Config(String),
59
60    #[error("Invalid arguments: {0}")]
61    InvalidArguments(String),
62
63    #[error("Git error: {0}")]
64    Git(String),
65
66    #[error("Registry error: {0}")]
67    Registry(String),
68
69    #[error("Core error: {0}")]
70    Core(#[from] governor_core::Error),
71
72    #[error("IO error: {0}")]
73    StdIo(#[from] std::io::Error),
74
75    #[error("Serialization error: {0}")]
76    Serialization(String),
77}
78
79impl From<String> for Error {
80    fn from(s: String) -> Self {
81        Self::Cli(s)
82    }
83}
84
85impl From<governor_application::ApplicationError> for Error {
86    fn from(error: governor_application::ApplicationError) -> Self {
87        match error {
88            governor_application::ApplicationError::InvalidArguments(message) => {
89                Self::InvalidArguments(message)
90            }
91            governor_application::ApplicationError::Workspace(message) => Self::Config(message),
92            governor_application::ApplicationError::SourceControl(error) => {
93                Self::Git(error.to_string())
94            }
95            governor_application::ApplicationError::Registry(error) => {
96                Self::Registry(error.to_string())
97            }
98            governor_application::ApplicationError::Checkpoint(error) => {
99                Self::Config(error.to_string())
100            }
101            governor_application::ApplicationError::Io(error) => Self::StdIo(error),
102        }
103    }
104}
105
106impl Error {
107    #[must_use]
108    pub const fn exit_code(&self) -> CommandExitCode {
109        match self {
110            Self::Cli(_) | Self::InvalidArguments(_) => CommandExitCode::InvalidArguments,
111            Self::Config(_) => CommandExitCode::ConfigError,
112            Self::Git(_) => CommandExitCode::GitError,
113            Self::Registry(_) => CommandExitCode::RegistryError,
114            Self::Core(_) | Self::StdIo(_) | Self::Serialization(_) => {
115                CommandExitCode::GeneralError
116            }
117        }
118    }
119}