feature/project-new-structure
claude/smbcloud-github-app-k9641p
development
feature/apps
feature/build-release
feature/ci-docs
feature/ci-ruby-gems
feature/cicd
feature/completion
feature/dist-nuget
feature/fix-ci-sdk-pypi-rubygem
feature/fix-clippy-on-stable-channel
feature/fix-deployment-script
feature/github-email
feature/gresiq-v1
feature/project-new-structure
feature/rsync-deploy
feature/ruby-runner
feature/sdk-npm
feature/sdk-workflows
feature/smbcloud-cli-release-npm
feature/smbcloud-deploy
feature/wasm
main
release/v0.7.4
| 1 | use { |
| 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)] |
| 13 | pub enum ErrorResponse { |
| 14 | Error { |
| 15 | error_code: ErrorCode, |
| 16 | message: String, |
| 17 | }, |
| 18 | } |
| 19 | |
| 20 | impl 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)] |
| 28 | pub 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("Cancelled.")] |
| 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 | |
| 71 | impl 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.", |
| 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 | } |