Skip to main content

muxi_rust/
errors.rs

1use thiserror::Error;
2
3#[derive(Error, Debug)]
4pub enum MuxiError {
5    #[error("Authentication error ({code}): {message}")]
6    Authentication { code: String, message: String, status: u16 },
7    
8    #[error("Authorization error ({code}): {message}")]
9    Authorization { code: String, message: String, status: u16 },
10    
11    #[error("Not found ({code}): {message}")]
12    NotFound { code: String, message: String, status: u16 },
13    
14    #[error("Conflict ({code}): {message}")]
15    Conflict { code: String, message: String, status: u16 },
16    
17    #[error("Validation error ({code}): {message}")]
18    Validation { code: String, message: String, status: u16 },
19    
20    #[error("Rate limited: {message} (retry after {retry_after:?}s)")]
21    RateLimit { message: String, status: u16, retry_after: Option<u32> },
22    
23    #[error("Server error ({code}): {message}")]
24    Server { code: String, message: String, status: u16 },
25    
26    #[error("Connection error: {0}")]
27    Connection(String),
28    
29    #[error("Request error: {0}")]
30    Request(#[from] reqwest::Error),
31    
32    #[error("JSON error: {0}")]
33    Json(#[from] serde_json::Error),
34    
35    #[error("Unknown error ({code}): {message}")]
36    Unknown { code: String, message: String, status: u16 },
37}
38
39impl MuxiError {
40    pub fn from_response(status: u16, code: Option<String>, message: String, retry_after: Option<u32>) -> Self {
41        let code = code.unwrap_or_default();
42        match status {
43            401 => MuxiError::Authentication { code: if code.is_empty() { "UNAUTHORIZED".to_string() } else { code }, message, status },
44            403 => MuxiError::Authorization { code: if code.is_empty() { "FORBIDDEN".to_string() } else { code }, message, status },
45            404 => MuxiError::NotFound { code: if code.is_empty() { "NOT_FOUND".to_string() } else { code }, message, status },
46            409 => MuxiError::Conflict { code: if code.is_empty() { "CONFLICT".to_string() } else { code }, message, status },
47            422 => MuxiError::Validation { code: if code.is_empty() { "VALIDATION_ERROR".to_string() } else { code }, message, status },
48            429 => MuxiError::RateLimit { message, status, retry_after },
49            500..=504 => MuxiError::Server { code: if code.is_empty() { "SERVER_ERROR".to_string() } else { code }, message, status },
50            _ => MuxiError::Unknown { code: if code.is_empty() { "ERROR".to_string() } else { code }, message, status },
51        }
52    }
53}
54
55pub type Result<T> = std::result::Result<T, MuxiError>;