Skip to main content

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