Skip to main content

energy_api/
error.rs

1//! Unified error type for the `energy-api` crate.
2
3use thiserror::Error;
4
5/// All errors that can be returned by the energy-api crate.
6#[derive(Debug, Error)]
7pub enum Error {
8    /// The remote service responded with a non-success HTTP status.
9    #[error("HTTP {status}: {body}")]
10    Http { status: u16, body: String },
11
12    /// The server returned a 307 Temporary Redirect — the caller should
13    /// follow the given URL and retry the request there.
14    #[error("Redirect to: {url}")]
15    Redirect { url: String },
16
17    /// A requested directory record does not exist.
18    #[error("record not found")]
19    NotFound,
20
21    /// JSON serialization or deserialization failure.
22    #[error("JSON error: {0}")]
23    Json(#[from] serde_json::Error),
24
25    /// An invalid URL was supplied or returned by the server.
26    #[error("URL error: {0}")]
27    Url(#[from] url::ParseError),
28
29    /// JWS signature creation or verification failed.
30    #[error("signature error: {0}")]
31    Signature(String),
32
33    /// Transport-level failure (TLS, DNS, connection reset, …).
34    #[error("transport error: {0}")]
35    Transport(String),
36
37    /// The remote endpoint violated the API protocol.
38    #[error("protocol error: {0}")]
39    Protocol(String),
40}
41
42#[cfg(feature = "client")]
43impl From<reqwest::Error> for Error {
44    fn from(e: reqwest::Error) -> Self {
45        if let Some(status) = e.status() {
46            Error::Http {
47                status: status.as_u16(),
48                body: e.to_string(),
49            }
50        } else {
51            Error::Transport(e.to_string())
52        }
53    }
54}
55
56#[cfg(feature = "websocket")]
57impl From<tokio_tungstenite::tungstenite::Error> for Error {
58    fn from(e: tokio_tungstenite::tungstenite::Error) -> Self {
59        Error::Transport(e.to_string())
60    }
61}