axene_mailer/error.rs
1//! Error type raised by the SDK.
2
3use std::fmt;
4
5/// Raised for any non-2xx API response, or for a transport failure that
6/// survives all retries.
7///
8/// Inspect [`AxeneError::status`] and [`AxeneError::code`] to branch on
9/// specific failures (for example a `422` with code `"invalid"`). A `status`
10/// of `0` indicates a transport/network failure with no HTTP response.
11#[derive(Debug, Clone)]
12pub struct AxeneError {
13 /// HTTP status code. `0` indicates a transport/network failure (no response).
14 pub status: u16,
15 /// Machine-readable error code from the API body, when present.
16 pub code: Option<String>,
17 /// Human-readable error message.
18 pub message: String,
19}
20
21impl AxeneError {
22 /// Build an error with an explicit status, message, and optional code.
23 pub fn new(status: u16, message: impl Into<String>, code: Option<String>) -> Self {
24 Self {
25 status,
26 code,
27 message: message.into(),
28 }
29 }
30
31 /// Build a transport-level error (no HTTP response was received).
32 pub fn transport(message: impl Into<String>) -> Self {
33 Self {
34 status: 0,
35 code: None,
36 message: message.into(),
37 }
38 }
39}
40
41impl fmt::Display for AxeneError {
42 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43 match &self.code {
44 Some(code) => write!(f, "Axene error {} ({}): {}", self.status, code, self.message),
45 None => write!(f, "Axene error {}: {}", self.status, self.message),
46 }
47 }
48}
49
50impl std::error::Error for AxeneError {}
51
52/// Convenience alias for results returned by the SDK.
53pub type Result<T> = std::result::Result<T, AxeneError>;