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 {
11 /// HTTP status code (e.g. `400`, `503`).
12 status: u16,
13 /// Response body text.
14 body: String,
15 },
16
17 /// The server returned a 307 Temporary Redirect — the caller should
18 /// follow the given URL and retry the request there.
19 #[error("Redirect to: {url}")]
20 Redirect {
21 /// Redirect target URL.
22 url: String,
23 },
24
25 /// A requested directory record does not exist.
26 #[error("record not found")]
27 NotFound,
28
29 /// JSON serialization or deserialization failure.
30 #[error("JSON error: {0}")]
31 Json(#[from] serde_json::Error),
32
33 /// An invalid URL was supplied or returned by the server.
34 #[error("URL error: {0}")]
35 Url(#[from] url::ParseError),
36
37 /// JWS signature creation or verification failed.
38 #[error("signature error: {0}")]
39 Signature(String),
40
41 /// Transport-level failure (TLS, DNS, connection reset, …).
42 #[error("transport error: {0}")]
43 Transport(String),
44
45 /// The remote endpoint violated the API protocol.
46 #[error("protocol error: {0}")]
47 Protocol(String),
48
49 /// A BDEW identifier failed validation (length, alphabet or check digit).
50 ///
51 /// Surfaced as HTTP 400: the caller supplied a malformed MaLo-, MeLo-,
52 /// NeLo-, SR- or TR-ID, and accepting it would let a bad identifier enter
53 /// the identification path.
54 #[error("invalid identifier: {0}")]
55 InvalidIdentifier(String),
56}
57
58#[cfg(feature = "client")]
59impl From<reqwest::Error> for Error {
60 fn from(e: reqwest::Error) -> Self {
61 if let Some(status) = e.status() {
62 Error::Http {
63 status: status.as_u16(),
64 body: e.to_string(),
65 }
66 } else {
67 Error::Transport(e.to_string())
68 }
69 }
70}
71
72#[cfg(feature = "websocket")]
73impl From<tokio_tungstenite::tungstenite::Error> for Error {
74 fn from(e: tokio_tungstenite::tungstenite::Error) -> Self {
75 Error::Transport(e.to_string())
76 }
77}