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    /// Base64 decode error
56    #[error("Decode error: {0}")]
57    DecodeError(String),
58
59    /// I/O error
60    #[error("I/O error: {0}")]
61    IoError(String),
62
63    /// Captioning error (no alignment segments available)
64    #[error("Captioning error: {0}")]
65    CaptioningError(String),
66}
67
68impl TypecastError {
69    /// Create an error from an HTTP response status code and optional error response
70    pub fn from_response(status_code: u16, error_response: Option<ErrorResponse>) -> Self {
71        let detail = error_response
72            .map(|e| e.detail)
73            .unwrap_or_else(|| "Unknown error".to_string());
74
75        match status_code {
76            400 => TypecastError::BadRequest { detail },
77            401 => TypecastError::Unauthorized { detail },
78            402 => TypecastError::PaymentRequired { detail },
79            403 => TypecastError::Forbidden { detail },
80            404 => TypecastError::NotFound { detail },
81            422 => TypecastError::ValidationError { detail },
82            429 => TypecastError::RateLimited { detail },
83            500..=599 => TypecastError::ServerError { detail },
84            _ => TypecastError::Unknown { status_code, detail },
85        }
86    }
87
88    /// Check if this error is a bad request error
89    pub fn is_bad_request(&self) -> bool {
90        matches!(self, TypecastError::BadRequest { .. })
91    }
92
93    /// Check if this error is an unauthorized error
94    pub fn is_unauthorized(&self) -> bool {
95        matches!(self, TypecastError::Unauthorized { .. })
96    }
97
98    /// Check if this error is a payment required error
99    pub fn is_payment_required(&self) -> bool {
100        matches!(self, TypecastError::PaymentRequired { .. })
101    }
102
103    /// Check if this error is a forbidden error
104    pub fn is_forbidden(&self) -> bool {
105        matches!(self, TypecastError::Forbidden { .. })
106    }
107
108    /// Check if this error is a not found error
109    pub fn is_not_found(&self) -> bool {
110        matches!(self, TypecastError::NotFound { .. })
111    }
112
113    /// Check if this error is a validation error
114    pub fn is_validation_error(&self) -> bool {
115        matches!(self, TypecastError::ValidationError { .. })
116    }
117
118    /// Check if this error is a rate limit error
119    pub fn is_rate_limited(&self) -> bool {
120        matches!(self, TypecastError::RateLimited { .. })
121    }
122
123    /// Check if this error is a server error
124    pub fn is_server_error(&self) -> bool {
125        matches!(self, TypecastError::ServerError { .. })
126    }
127
128    /// Get the status code if available
129    pub fn status_code(&self) -> Option<u16> {
130        match self {
131            TypecastError::BadRequest { .. } => Some(400),
132            TypecastError::Unauthorized { .. } => Some(401),
133            TypecastError::PaymentRequired { .. } => Some(402),
134            TypecastError::Forbidden { .. } => Some(403),
135            TypecastError::NotFound { .. } => Some(404),
136            TypecastError::ValidationError { .. } => Some(422),
137            TypecastError::RateLimited { .. } => Some(429),
138            TypecastError::ServerError { .. } => Some(500),
139            TypecastError::Unknown { status_code, .. } => Some(*status_code),
140            _ => None,
141        }
142    }
143}
144
145/// Result type alias for Typecast operations
146pub type Result<T> = std::result::Result<T, TypecastError>;