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}