smbcloud_model/
error_codes.rs

1use {
2    core::fmt,
3    log::debug,
4    serde::{Deserialize, Serialize},
5    serde_repr::{Deserialize_repr, Serialize_repr},
6    std::fmt::{Display, Formatter},
7    strum_macros::{EnumIter, IntoStaticStr},
8    thiserror::Error,
9};
10
11#[derive(Error, Serialize, Deserialize, Debug)]
12#[serde(untagged)]
13pub enum ErrorResponse {
14    Error {
15        error_code: ErrorCode,
16        message: String,
17    },
18}
19
20impl Display for ErrorResponse {
21    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
22        write!(f, "{:?}", self)
23    }
24}
25
26#[derive(Error, Serialize_repr, Deserialize_repr, Debug, EnumIter, IntoStaticStr)]
27#[repr(i32)]
28pub enum ErrorCode {
29    // Generic errors
30    #[error("Unknown error.")]
31    Unknown = 0,
32    #[error("Parse error.")]
33    ParseError = 1,
34    #[error("Network error. Please check your internet connection and try again.")]
35    NetworkError = 2,
36    #[error("Input error")]
37    InputError = 3,
38    #[error("Missing config file. Please regenerate with 'smb init'.")]
39    MissingConfig = 4,
40    // #[error("Missing id in repository. Please regenerate with 'smb init'.")]
41    // MissingId,
42    #[error("Cancel operation.")]
43    Cancel = 5,
44    // Account
45    #[error("Unauthorized access.")]
46    Unauthorized = 100,
47    #[error("Invalid params.")]
48    InvalidParams = 101,
49    // Account not ready errors.
50    #[error("Email not found.")]
51    EmailNotFound = 1000,
52    #[error("Email unverified.")]
53    EmailNotVerified = 1001,
54    #[error("Email confirmation failed.")]
55    EmailConfirmationFailed = 1002,
56    #[error("Password is unset.")]
57    PasswordNotSet = 1003,
58    #[error("GitHub email is not connected.")]
59    GitHubEmailNotConnected = 1004,
60    #[error("Email already exists.")]
61    EmailAlreadyExist = 1005,
62    #[error("Invalid password.")]
63    InvalidPassword = 1006,
64    // Projects
65    #[error("Project not found.")]
66    ProjectNotFound = 2000,
67    #[error("Runner not supported.")]
68    UnsupportedRunner = 2001,
69}
70
71impl ErrorCode {
72    /// Cannot expose the ErrorCode enum directly to Ruby,
73    /// so we need to get it from i32.
74    pub fn from_i32(value: i32) -> Self {
75        match value {
76            // Generic
77            100 => ErrorCode::Unauthorized,
78            101 => ErrorCode::InvalidParams,
79            // Account not ready errors
80            1000 => ErrorCode::EmailNotFound,
81            1001 => ErrorCode::EmailNotVerified,
82            1002 => ErrorCode::EmailConfirmationFailed,
83            1003 => ErrorCode::PasswordNotSet,
84            1004 => ErrorCode::GitHubEmailNotConnected,
85            1005 => ErrorCode::EmailAlreadyExist,
86            1006 => ErrorCode::InvalidPassword,
87            // Projects
88            2000 => ErrorCode::ProjectNotFound, // Projects
89            2001 => ErrorCode::UnsupportedRunner,
90            // Generic errors
91            5 => ErrorCode::Cancel,
92            4 => ErrorCode::MissingConfig,
93            3 => ErrorCode::InputError,
94            2 => ErrorCode::ParseError,
95            1 => ErrorCode::NetworkError,
96            // Fallback
97            _ => ErrorCode::Unknown,
98        }
99    }
100
101    // This could be better.
102    pub fn message(&self, l: Option<String>) -> &str {
103        debug!("Language code: {:?}, {}", l, self);
104        match self {
105            ErrorCode::Unknown => "Unknown error.",
106            // Networking
107            ErrorCode::ParseError => "Parse error.",
108            ErrorCode::NetworkError => {
109                "Network error. Please check your internet connection and try again."
110            }
111            // Generic
112            ErrorCode::Unauthorized => "Unauthorized access.",
113            ErrorCode::InvalidParams => "Invalid parameters.",
114            // Account not ready errors
115            ErrorCode::EmailNotFound => "Email not found.",
116            ErrorCode::EmailNotVerified => "Email not verified.",
117            ErrorCode::EmailConfirmationFailed => "Email confirmation faile.",
118            ErrorCode::PasswordNotSet => "Password is not set.",
119            ErrorCode::GitHubEmailNotConnected => "GitHub email is not connected.",
120            ErrorCode::EmailAlreadyExist => "Email already exists.",
121            ErrorCode::InvalidPassword => "Invalid password.",
122            // CLI Generic errors
123            ErrorCode::InputError => "Input error.",
124            ErrorCode::MissingConfig => "Missing config.",
125            ErrorCode::Cancel => "Cancelled operation.",
126            // Projects
127            ErrorCode::ProjectNotFound => "Project not found.",
128            ErrorCode::UnsupportedRunner => "Unsupported runner.",
129        }
130    }
131
132    pub fn rb_constant_name(&self) -> String {
133        // Using IntoStaticStr to get the variant name directly.
134        // self.into() will return a &'static str representing the variant name.
135        let variant_name_static_str: &'static str = self.into();
136        variant_name_static_str.to_string()
137    }
138}