Skip to main content

clicksend_rs/
errors.rs

1//! Error type returned by every API call.
2
3use thiserror::Error;
4
5/// Anything that can go wrong talking to ClickSend.
6#[derive(Debug, Error)]
7pub enum ClickSendError {
8    /// Underlying transport error (DNS, TLS, connection, decode body).
9    #[error("http error: {0}")]
10    Http(#[from] reqwest::Error),
11
12    /// HTTP 401 — bad username or api_key.
13    #[error("unauthorized — bad username or api key")]
14    Unauthorized,
15
16    /// HTTP 404 — resource missing. Body included for debugging.
17    #[error("not found: {0}")]
18    NotFound(String),
19
20    /// Non-success HTTP status (4xx/5xx) that is not 401/404/429.
21    /// Use [`ClickSendError::Api`] for the case where ClickSend returns
22    /// HTTP 200 but an error envelope.
23    #[error("api error ({code}): {message}")]
24    Http4xx5xx {
25        /// HTTP status code.
26        code: u16,
27        /// Raw response body.
28        message: String,
29    },
30
31    /// HTTP 200 with `response_code != "SUCCESS"`. ClickSend returns
32    /// logical errors this way (bad sender id, blocked country, throttled, …).
33    #[error("api error: {code} — {message}")]
34    Api {
35        /// ClickSend `response_code` (e.g. `"ERROR"`, `"INVALID_FROM"`).
36        code: String,
37        /// ClickSend `response_msg`.
38        message: String,
39        /// Raw envelope body for debugging.
40        body: String,
41    },
42
43    /// JSON decode failed. Includes the offending body so you can file a bug.
44    #[error("decode error: {message}\nbody: {body}")]
45    Decode {
46        /// `serde_json` error message.
47        message: String,
48        /// Raw body that failed to decode.
49        body: String,
50    },
51
52    /// HTTP 429 after retries are exhausted.
53    #[error("rate limited (retry-after: {retry_after_secs:?}s)")]
54    RateLimited {
55        /// `Retry-After` header value, if present.
56        retry_after_secs: Option<u64>,
57    },
58
59    /// Builder rejected something — empty creds, etc.
60    #[error("invalid config: {0}")]
61    InvalidConfig(String),
62}