tencentcloud_sms_sdk/
error.rs

1//! Error types for the TencentCloud SMS SDK
2
3use thiserror::Error;
4
5/// Result type alias for TencentCloud operations
6pub type Result<T> = std::result::Result<T, TencentCloudError>;
7
8/// Main error type for TencentCloud SDK operations
9#[derive(Error, Debug)]
10pub enum TencentCloudError {
11    /// Network-related errors
12    #[error("Network error: {0}")]
13    Network(#[from] reqwest::Error),
14
15    /// JSON serialization/deserialization errors
16    #[error("JSON error: {0}")]
17    Json(#[from] serde_json::Error),
18
19    /// API errors returned by TencentCloud
20    #[error("API error: {code} - {message}")]
21    Api {
22        /// Error code returned by the API
23        code: String,
24        /// Error message returned by the API
25        message: String,
26        /// Request ID for debugging
27        request_id: Option<String>,
28    },
29
30    /// Authentication errors
31    #[error("Authentication error: {0}")]
32    Auth(String),
33
34    /// Configuration errors
35    #[error("Configuration error: {0}")]
36    Config(String),
37
38    /// Parameter validation errors
39    #[error("Parameter error: {0}")]
40    Parameter(String),
41
42    /// Signature generation errors
43    #[error("Signature error: {0}")]
44    Signature(String),
45
46    /// Timeout errors
47    #[error("Timeout error: {0}")]
48    Timeout(String),
49
50    /// Generic errors
51    #[error("Error: {0}")]
52    Other(String),
53}
54
55impl TencentCloudError {
56    /// Create a new API error
57    pub fn api<S: Into<String>>(code: S, message: S) -> Self {
58        Self::Api {
59            code: code.into(),
60            message: message.into(),
61            request_id: None,
62        }
63    }
64
65    /// Create a new API error with request ID
66    pub fn api_with_request_id<S: Into<String>>(
67        code: S,
68        message: S,
69        request_id: Option<S>,
70    ) -> Self {
71        Self::Api {
72            code: code.into(),
73            message: message.into(),
74            request_id: request_id.map(|s| s.into()),
75        }
76    }
77
78    /// Create a new authentication error
79    pub fn auth<S: Into<String>>(message: S) -> Self {
80        Self::Auth(message.into())
81    }
82
83    /// Create a new configuration error
84    pub fn config<S: Into<String>>(message: S) -> Self {
85        Self::Config(message.into())
86    }
87
88    /// Create a new parameter error
89    pub fn parameter<S: Into<String>>(message: S) -> Self {
90        Self::Parameter(message.into())
91    }
92
93    /// Create a new signature error
94    pub fn signature<S: Into<String>>(message: S) -> Self {
95        Self::Signature(message.into())
96    }
97
98    /// Create a new timeout error
99    pub fn timeout<S: Into<String>>(message: S) -> Self {
100        Self::Timeout(message.into())
101    }
102
103    /// Create a new generic error
104    pub fn other<S: Into<String>>(message: S) -> Self {
105        Self::Other(message.into())
106    }
107
108    /// Get error code if this is an API error
109    pub fn code(&self) -> Option<&str> {
110        match self {
111            Self::Api { code, .. } => Some(code),
112            _ => None,
113        }
114    }
115
116    /// Get request ID if available
117    pub fn request_id(&self) -> Option<&str> {
118        match self {
119            Self::Api { request_id, .. } => request_id.as_deref(),
120            _ => None,
121        }
122    }
123
124    /// Check if this is a specific API error code
125    pub fn is_api_error(&self, error_code: &str) -> bool {
126        match self {
127            Self::Api { code, .. } => code == error_code,
128            _ => false,
129        }
130    }
131
132    /// Check if this is a network error
133    pub fn is_network_error(&self) -> bool {
134        matches!(self, Self::Network(_))
135    }
136
137    /// Check if this is a timeout error
138    pub fn is_timeout_error(&self) -> bool {
139        matches!(self, Self::Timeout(_))
140    }
141
142    /// Print all error details (similar to C++ SDK)
143    pub fn print_all(&self) -> String {
144        match self {
145            Self::Api {
146                code,
147                message,
148                request_id,
149            } => {
150                if let Some(req_id) = request_id {
151                    format!("API Error: {} - {} (Request ID: {})", code, message, req_id)
152                } else {
153                    format!("API Error: {} - {}", code, message)
154                }
155            }
156            _ => self.to_string(),
157        }
158    }
159}
160
161/// Common API error codes
162pub mod error_codes {
163    /// Failed operation - signature incorrect or unapproved
164    pub const SIGNATURE_INCORRECT_OR_UNAPPROVED: &str =
165        "FailedOperation.SignatureIncorrectOrUnapproved";
166
167    /// Failed operation - template incorrect or unapproved
168    pub const TEMPLATE_INCORRECT_OR_UNAPPROVED: &str =
169        "FailedOperation.TemplateIncorrectOrUnapproved";
170
171    /// Unauthorized operation - SMS SDK app ID verify fail
172    pub const SMS_SDK_APP_ID_VERIFY_FAIL: &str = "UnauthorizedOperation.SmsSdkAppIdVerifyFail";
173
174    /// Invalid parameter - incorrect phone number
175    pub const INCORRECT_PHONE_NUMBER: &str = "InvalidParameterValue.IncorrectPhoneNumber";
176
177    /// Limit exceeded - phone number count limit
178    pub const PHONE_NUMBER_COUNT_LIMIT: &str = "LimitExceeded.PhoneNumberCountLimit";
179
180    /// Failed operation - insufficient balance in SMS package
181    pub const INSUFFICIENT_BALANCE: &str = "FailedOperation.InsufficientBalanceInSmsPackage";
182
183    /// Internal error - timeout
184    pub const TIMEOUT: &str = "InternalError.Timeout";
185
186    /// Request time exception
187    pub const REQUEST_TIME_EXCEPTION: &str = "InternalError.RequestTimeException";
188}