cellstate/
error.rs

1//! Error types for the CELLSTATE Rust SDK.
2//!
3//! Provides a unified error enum covering HTTP transport, API responses,
4//! serialization, and URL construction failures.
5
6use serde::{Deserialize, Serialize};
7use std::fmt;
8
9/// Error type returned by all `CellstateClient` operations.
10#[derive(Debug, thiserror::Error)]
11pub enum Error {
12    /// HTTP transport error (network failure, timeout, TLS, etc.).
13    #[error("HTTP error: {0}")]
14    Http(#[from] reqwest::Error),
15
16    /// API returned a structured error response.
17    #[error("API error ({status}): {body}")]
18    Api {
19        /// HTTP status code from the API.
20        status: u16,
21        /// Parsed error body (if available).
22        body: ApiErrorBody,
23    },
24
25    /// JSON serialization or deserialization error.
26    #[error("Serialization error: {0}")]
27    Serialization(#[from] serde_json::Error),
28
29    /// Binary decode error (e.g., MessagePack response body).
30    #[error("Decode error: {0}")]
31    Decode(String),
32
33    /// Invalid URL construction (bad base URL or path).
34    #[error("Invalid URL: {0}")]
35    InvalidUrl(#[from] url::ParseError),
36}
37
38/// Structured error body from the CELLSTATE API.
39///
40/// Mirrors the `ApiError` type from `cellstate-api`, using snake_case for
41/// wire compatibility.
42#[derive(Debug, Clone, Serialize, Deserialize)]
43pub struct ApiErrorBody {
44    /// Error code (e.g., "ENTITY_NOT_FOUND", "UNAUTHORIZED").
45    pub code: String,
46    /// Human-readable error message.
47    pub message: String,
48    /// Optional additional details.
49    #[serde(skip_serializing_if = "Option::is_none")]
50    pub details: Option<serde_json::Value>,
51}
52
53impl fmt::Display for ApiErrorBody {
54    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55        write!(f, "[{}] {}", self.code, self.message)
56    }
57}
58
59/// Result type alias for CELLSTATE SDK operations.
60pub type Result<T> = std::result::Result<T, Error>;