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>;