limitless/errors.rs
1//! Error types for the Limitless Exchange API client.
2//!
3//! `LimitlessContentError` captures error details returned by the API itself.
4//! `LimitlessError` is the top-level error enum covering API errors, network
5//! failures, serialization issues, and validation errors.
6
7use crate::prelude::*;
8
9/// Represents an error returned by the Limitless API in the response body.
10///
11/// The `message` field contains the human-readable error description.
12/// The `code` field (if present) contains a machine-readable error code.
13#[derive(Debug, Deserialize, Display)]
14#[display("{}", message)]
15pub struct LimitlessContentError {
16 /// Human-readable error message from the API.
17 pub message: String,
18 /// Optional machine-readable error code.
19 #[serde(default)]
20 pub code: Option<String>,
21}
22
23/// Top-level error type covering all possible failures when interacting
24/// with the Limitless Exchange API.
25#[derive(Debug, Error)]
26pub enum LimitlessError {
27 /// The Limitless API returned an error response (4xx/5xx with a body).
28 #[error("Limitless API error: {0}")]
29 ApiError(LimitlessContentError),
30
31 /// Failed to send a value on an internal channel (WebSocket event loop).
32 #[error("Failed to emit value on channel: {underlying}")]
33 ChannelSendError { underlying: String },
34
35 /// Request parameters failed client-side validation before being sent.
36 #[error("Validation error: {0}")]
37 ValidationError(String),
38
39 /// Reqwest HTTP client error (network, DNS, TLS, timeout).
40 #[error(transparent)]
41 ReqError(#[from] reqwest::Error),
42
43 /// Invalid HTTP header value provided.
44 #[error(transparent)]
45 InvalidHeaderError(#[from] reqwest::header::InvalidHeaderValue),
46
47 /// Standard I/O error.
48 #[error(transparent)]
49 IoError(#[from] std::io::Error),
50
51 /// Failed to parse a string as a floating-point number.
52 #[error(transparent)]
53 ParseFloatError(#[from] std::num::ParseFloatError),
54
55 /// URL parsing failure.
56 #[error(transparent)]
57 UrlParserError(#[from] url::ParseError),
58
59 /// JSON serialization/deserialization error.
60 #[error(transparent)]
61 Json(#[from] serde_json::Error),
62
63 /// WebSocket protocol / transport error.
64 #[error(transparent)]
65 Tungstenite(#[from] tokio_tungstenite::tungstenite::Error),
66
67 /// System time error (clock may be before Unix epoch).
68 #[error(transparent)]
69 TimestampError(#[from] std::time::SystemTimeError),
70
71 /// Generic serde deserialization error.
72 #[error(transparent)]
73 SerdeError(#[from] serde::de::value::Error),
74
75 /// The server returned 500 Internal Server Error.
76 #[error("Internal Server Error")]
77 InternalServerError,
78
79 /// The server returned 503 Service Unavailable.
80 #[error("Service Unavailable")]
81 ServiceUnavailable,
82
83 /// The server returned 401 Unauthorized — check your API key/token.
84 #[error("Unauthorized — check API key or token")]
85 Unauthorized,
86
87 /// Rate-limited (429 Too Many Requests). Retry with backoff.
88 #[error("Rate limited — retry with exponential backoff")]
89 RateLimited,
90
91 /// The server returned an unexpected status code.
92 #[error("Unexpected status code: {0}")]
93 StatusCode(u16),
94
95 /// A catch-all for errors that do not fit other variants.
96 #[error("Limitless error: {0}")]
97 Base(String),
98}
99
100impl From<String> for LimitlessError {
101 fn from(err: String) -> Self {
102 LimitlessError::Base(err)
103 }
104}