Skip to main content

agile_config_client/
error.rs

1//! Typed errors returned by the `AgileConfig` client.
2
3/// Failures that can occur while configuring, loading, or connecting.
4#[derive(Debug, thiserror::Error)]
5#[non_exhaustive]
6pub enum Error {
7    /// `app_id` was empty or whitespace.
8    #[error("app_id must not be empty")]
9    EmptyAppId,
10    /// No usable server node URLs were provided.
11    #[error("at least one server node is required")]
12    EmptyNodes,
13    /// A node URL could not be converted to a WebSocket endpoint.
14    #[error("invalid server node URL: {0}")]
15    InvalidNode(String),
16    /// Every node failed and no local cache was available.
17    #[error("failed to load configuration from all nodes")]
18    LoadFailed,
19    /// The server returned a non-success HTTP status.
20    #[error("HTTP {status} from {url}")]
21    HttpStatus {
22        /// Request URL.
23        url: String,
24        /// HTTP status code.
25        status: u16,
26    },
27    /// Underlying HTTP client error.
28    #[error(transparent)]
29    Request(#[from] reqwest::Error),
30    /// WebSocket handshake or I/O failed.
31    #[error("websocket error: {0}")]
32    WebSocket(String),
33    /// The configuration payload could not be decoded.
34    #[error("failed to parse configuration payload: {0}")]
35    Protocol(#[from] serde_json::Error),
36    /// Reading or writing the local cache file failed.
37    #[error("cache error: {0}")]
38    Cache(String),
39    /// [`CacheOptions::encrypt`](crate::CacheOptions::encrypt) is `true`, but
40    /// the crate was built without the `cache-encrypt` feature.
41    #[error("cache encryption requires the `cache-encrypt` cargo feature")]
42    CacheEncryptDisabled,
43}
44
45impl Error {
46    pub(crate) fn websocket<E: std::fmt::Display>(error: E) -> Self {
47        Self::WebSocket(error.to_string())
48    }
49
50    pub(crate) fn cache<E: std::fmt::Display>(error: E) -> Self {
51        Self::Cache(error.to_string())
52    }
53}
54
55#[cfg(test)]
56mod tests {
57    use super::Error;
58
59    #[test]
60    fn empty_app_id_displays_clear_message() {
61        assert_eq!(Error::EmptyAppId.to_string(), "app_id must not be empty");
62    }
63}