Skip to main content

typecast_rust/
errors.rs

1//! Error types for the Typecast SDK
2//!
3//! This module contains all error types that can be returned by the SDK.
4
5use crate::models::ErrorResponse;
6use thiserror::Error;
7
8/// Error type for Typecast API operations
9#[derive(Error, Debug)]
10pub enum TypecastError {
11    /// Bad Request - The request was invalid or cannot be served
12    #[error("Bad Request - {detail}")]
13    BadRequest { detail: String },
14
15    /// Unauthorized - Invalid or missing API key
16    #[error("Unauthorized - Invalid or missing API key")]
17    Unauthorized { detail: String },
18
19    /// Payment Required - Insufficient credits to complete the request
20    #[error("Payment Required - Insufficient credits")]
21    PaymentRequired { detail: String },
22
23    /// Forbidden - Access denied
24    #[error("Forbidden - Access denied")]
25    Forbidden { detail: String },
26
27    /// Not Found - The requested resource does not exist
28    #[error("Not Found - {detail}")]
29    NotFound { detail: String },
30
31    /// Validation Error - The request data failed validation
32    #[error("Validation Error - {detail}")]
33    ValidationError { detail: String },
34
35    /// Too Many Requests - Rate limit exceeded
36    #[error("Too Many Requests - Rate limit exceeded")]
37    RateLimited { detail: String },
38
39    /// Internal Server Error - Something went wrong on the server
40    #[error("Internal Server Error - {detail}")]
41    ServerError { detail: String },
42
43    /// HTTP client error
44    #[error("HTTP error: {0}")]
45    HttpError(#[from] reqwest::Error),
46
47    /// JSON serialization/deserialization error
48    #[error("JSON error: {0}")]
49    JsonError(#[from] serde_json::Error),
50
51    /// Unknown error with status code
52    #[error("API error (status {status_code}): {detail}")]
53    Unknown { status_code: u16, detail: String },
54}
55
56impl TypecastError {
57    /// Create an error from an HTTP response status code and optional error response
58    pub fn from_response(status_code: u16, error_response: Option<ErrorResponse>) -> Self {
59        let detail = error_response
60            .map(|e| e.detail)
61            .unwrap_or_else(|| "Unknown error".to_string());
62
63        match status_code {
64            400 => TypecastError::BadRequest { detail },
65            401 => TypecastError::Unauthorized { detail },
66            402 => TypecastError::PaymentRequired { detail },
67            403 => TypecastError::Forbidden { detail },
68            404 => TypecastError::NotFound { detail },
69            422 => TypecastError::ValidationError { detail },
70            429 => TypecastError::RateLimited { detail },
71            500..=599 => TypecastError::ServerError { detail },
72            _ => TypecastError::Unknown { status_code, detail },
73        }
74    }
75
76    /// Check if this error is a bad request error
77    pub fn is_bad_request(&self) -> bool {
78        matches!(self, TypecastError::BadRequest { .. })
79    }
80
81    /// Check if this error is an unauthorized error
82    pub fn is_unauthorized(&self) -> bool {
83        matches!(self, TypecastError::Unauthorized { .. })
84    }
85
86    /// Check if this error is a payment required error
87    pub fn is_payment_required(&self) -> bool {
88        matches!(self, TypecastError::PaymentRequired { .. })
89    }
90
91    /// Check if this error is a forbidden error
92    pub fn is_forbidden(&self) -> bool {
93        matches!(self, TypecastError::Forbidden { .. })
94    }
95
96    /// Check if this error is a not found error
97    pub fn is_not_found(&self) -> bool {
98        matches!(self, TypecastError::NotFound { .. })
99    }
100
101    /// Check if this error is a validation error
102    pub fn is_validation_error(&self) -> bool {
103        matches!(self, TypecastError::ValidationError { .. })
104    }
105
106    /// Check if this error is a rate limit error
107    pub fn is_rate_limited(&self) -> bool {
108        matches!(self, TypecastError::RateLimited { .. })
109    }
110
111    /// Check if this error is a server error
112    pub fn is_server_error(&self) -> bool {
113        matches!(self, TypecastError::ServerError { .. })
114    }
115
116    /// Get the status code if available
117    pub fn status_code(&self) -> Option<u16> {
118        match self {
119            TypecastError::BadRequest { .. } => Some(400),
120            TypecastError::Unauthorized { .. } => Some(401),
121            TypecastError::PaymentRequired { .. } => Some(402),
122            TypecastError::Forbidden { .. } => Some(403),
123            TypecastError::NotFound { .. } => Some(404),
124            TypecastError::ValidationError { .. } => Some(422),
125            TypecastError::RateLimited { .. } => Some(429),
126            TypecastError::ServerError { .. } => Some(500),
127            TypecastError::Unknown { status_code, .. } => Some(*status_code),
128            _ => None,
129        }
130    }
131}
132
133/// Result type alias for Typecast operations
134pub type Result<T> = std::result::Result<T, TypecastError>;