Skip to main content

lightcone_sdk/api/
error.rs

1//! API error types for the Lightcone REST API client.
2
3use thiserror::Error;
4
5/// API-specific error type for the Lightcone REST API client.
6#[derive(Debug, Error)]
7pub enum ApiError {
8    /// HTTP/network error from reqwest
9    #[error("HTTP error: {0}")]
10    Http(#[from] reqwest::Error),
11
12    /// Resource not found (404)
13    #[error("Not found: {0}")]
14    NotFound(String),
15
16    /// Invalid request parameters (400)
17    #[error("Bad request: {0}")]
18    BadRequest(String),
19
20    /// Permission denied, signature mismatch (403)
21    #[error("Permission denied: {0}")]
22    Forbidden(String),
23
24    /// Rate limited (429)
25    #[error("Rate limited: {0}")]
26    RateLimited(String),
27
28    /// Authentication required (401)
29    #[error("Unauthorized: {0}")]
30    Unauthorized(String),
31
32    /// Resource already exists (409)
33    #[error("Conflict: {0}")]
34    Conflict(String),
35
36    /// Server-side error (500)
37    #[error("Server error: {0}")]
38    ServerError(String),
39
40    /// JSON deserialization error
41    #[error("Deserialization error: {0}")]
42    Deserialize(String),
43
44    /// Invalid parameter provided
45    #[error("Invalid parameter: {0}")]
46    InvalidParameter(String),
47
48    /// Unexpected HTTP status code
49    #[error("Unexpected status {0}: {1}")]
50    UnexpectedStatus(u16, String),
51}
52
53/// Result type alias for API operations.
54pub type ApiResult<T> = Result<T, ApiError>;
55
56/// Error response format from the API.
57#[derive(Debug, Clone, serde::Deserialize)]
58pub struct ErrorResponse {
59    /// Error status (usually "error")
60    #[serde(default)]
61    pub status: Option<String>,
62    /// Human-readable error message
63    #[serde(alias = "error")]
64    pub message: Option<String>,
65    /// Additional error details
66    #[serde(default)]
67    pub details: Option<String>,
68}
69
70impl ErrorResponse {
71    /// Get the error message, preferring `message` over `details`.
72    pub fn get_message(&self) -> String {
73        self.message
74            .clone()
75            .or_else(|| self.details.clone())
76            .unwrap_or_else(|| "Unknown error".to_string())
77    }
78}