use thiserror::Error;
pub type Result<T> = std::result::Result<T, TencentCloudError>;
#[derive(Error, Debug)]
pub enum TencentCloudError {
#[error("Network error: {0}")]
Network(#[from] reqwest::Error),
#[error("JSON error: {0}")]
Json(#[from] serde_json::Error),
#[error("API error: {code} - {message}")]
Api {
code: String,
message: String,
request_id: Option<String>,
},
#[error("Authentication error: {0}")]
Auth(String),
#[error("Configuration error: {0}")]
Config(String),
#[error("Parameter error: {0}")]
Parameter(String),
#[error("Signature error: {0}")]
Signature(String),
#[error("Timeout error: {0}")]
Timeout(String),
#[error("Error: {0}")]
Other(String),
}
impl TencentCloudError {
pub fn api<S: Into<String>>(code: S, message: S) -> Self {
Self::Api {
code: code.into(),
message: message.into(),
request_id: None,
}
}
pub fn api_with_request_id<S: Into<String>>(
code: S,
message: S,
request_id: Option<S>,
) -> Self {
Self::Api {
code: code.into(),
message: message.into(),
request_id: request_id.map(|s| s.into()),
}
}
pub fn auth<S: Into<String>>(message: S) -> Self {
Self::Auth(message.into())
}
pub fn config<S: Into<String>>(message: S) -> Self {
Self::Config(message.into())
}
pub fn parameter<S: Into<String>>(message: S) -> Self {
Self::Parameter(message.into())
}
pub fn signature<S: Into<String>>(message: S) -> Self {
Self::Signature(message.into())
}
pub fn timeout<S: Into<String>>(message: S) -> Self {
Self::Timeout(message.into())
}
pub fn other<S: Into<String>>(message: S) -> Self {
Self::Other(message.into())
}
pub fn code(&self) -> Option<&str> {
match self {
Self::Api { code, .. } => Some(code),
_ => None,
}
}
pub fn request_id(&self) -> Option<&str> {
match self {
Self::Api { request_id, .. } => request_id.as_deref(),
_ => None,
}
}
pub fn is_api_error(&self, error_code: &str) -> bool {
match self {
Self::Api { code, .. } => code == error_code,
_ => false,
}
}
pub fn is_network_error(&self) -> bool {
matches!(self, Self::Network(_))
}
pub fn is_timeout_error(&self) -> bool {
matches!(self, Self::Timeout(_))
}
pub fn print_all(&self) -> String {
match self {
Self::Api {
code,
message,
request_id,
} => {
if let Some(req_id) = request_id {
format!("API Error: {} - {} (Request ID: {})", code, message, req_id)
} else {
format!("API Error: {} - {}", code, message)
}
}
_ => self.to_string(),
}
}
}
pub mod error_codes {
pub const SIGNATURE_INCORRECT_OR_UNAPPROVED: &str =
"FailedOperation.SignatureIncorrectOrUnapproved";
pub const TEMPLATE_INCORRECT_OR_UNAPPROVED: &str =
"FailedOperation.TemplateIncorrectOrUnapproved";
pub const SMS_SDK_APP_ID_VERIFY_FAIL: &str = "UnauthorizedOperation.SmsSdkAppIdVerifyFail";
pub const INCORRECT_PHONE_NUMBER: &str = "InvalidParameterValue.IncorrectPhoneNumber";
pub const PHONE_NUMBER_COUNT_LIMIT: &str = "LimitExceeded.PhoneNumberCountLimit";
pub const INSUFFICIENT_BALANCE: &str = "FailedOperation.InsufficientBalanceInSmsPackage";
pub const TIMEOUT: &str = "InternalError.Timeout";
pub const REQUEST_TIME_EXCEPTION: &str = "InternalError.RequestTimeException";
}