Skip to main content

polyoxide_core/
error.rs

1use thiserror::Error;
2
3/// Core API error types shared across Polyoxide clients
4#[derive(Error, Debug)]
5pub enum ApiError {
6    /// HTTP request failed
7    #[error("API error: {status} - {message}")]
8    Api { status: u16, message: String },
9
10    /// Authentication failed (401/403)
11    #[error("Authentication failed: {0}")]
12    Authentication(String),
13
14    /// Request validation failed (400)
15    #[error("Validation error: {0}")]
16    Validation(String),
17
18    /// Rate limit exceeded (429)
19    #[error("Rate limit exceeded")]
20    RateLimit,
21
22    /// Request timeout
23    #[error("Request timeout")]
24    Timeout,
25
26    /// Network error
27    #[error("Network error: {0}")]
28    Network(#[from] reqwest::Error),
29
30    /// JSON serialization/deserialization error
31    #[error("Serialization error: {0}")]
32    Serialization(#[from] serde_json::Error),
33
34    /// URL parsing error
35    #[error("URL error: {0}")]
36    Url(#[from] url::ParseError),
37}
38
39impl ApiError {
40    /// Create error from HTTP response
41    pub async fn from_response(response: reqwest::Response) -> Self {
42        let status = response.status().as_u16();
43
44        // Get the raw response text first for debugging
45        let body_text = response.text().await.unwrap_or_default();
46        tracing::error!("API error response body: {}", body_text);
47
48        let message = serde_json::from_str::<serde_json::Value>(&body_text)
49            .ok()
50            .and_then(|v| {
51                v.get("error")
52                    .or(v.get("message"))
53                    .and_then(|m| m.as_str())
54                    .map(String::from)
55            })
56            .unwrap_or_else(|| body_text.clone());
57
58        match status {
59            401 | 403 => Self::Authentication(message),
60            400 => Self::Validation(message),
61            429 => Self::RateLimit,
62            408 => Self::Timeout,
63            _ => Self::Api { status, message },
64        }
65    }
66}