Skip to main content

polyoxide_relay/
error.rs

1use thiserror::Error;
2
3/// Error types for relay operations.
4///
5/// Wraps underlying HTTP, serialization, and signing errors, plus relay-specific
6/// API failures and rate limiting.
7#[derive(Error, Debug)]
8pub enum RelayError {
9    #[error("Reqwest error: {0}")]
10    Reqwest(#[from] reqwest::Error),
11
12    #[error("URL parse error: {0}")]
13    UrlParse(#[from] url::ParseError),
14
15    #[error("Serde JSON error: {0}")]
16    SerdeJson(#[from] serde_json::Error),
17
18    #[error("Signer error: {0}")]
19    Signer(String),
20
21    #[error("Relayer API error: {0}")]
22    Api(String),
23
24    #[error("Rate limit exceeded")]
25    RateLimit,
26
27    #[error("Missing signer")]
28    MissingSigner,
29
30    #[error("Core API error: {0}")]
31    Core(#[from] polyoxide_core::ApiError),
32}
33
34#[cfg(test)]
35mod tests {
36    use super::*;
37
38    #[test]
39    fn test_signer_error_display() {
40        let err = RelayError::Signer("bad key".into());
41        assert_eq!(format!("{err}"), "Signer error: bad key");
42    }
43
44    #[test]
45    fn test_api_error_display() {
46        let err = RelayError::Api("server returned 500".into());
47        assert_eq!(format!("{err}"), "Relayer API error: server returned 500");
48    }
49
50    #[test]
51    fn test_rate_limit_display() {
52        let err = RelayError::RateLimit;
53        assert_eq!(format!("{err}"), "Rate limit exceeded");
54    }
55
56    #[test]
57    fn test_missing_signer_display() {
58        let err = RelayError::MissingSigner;
59        assert_eq!(format!("{err}"), "Missing signer");
60    }
61
62    #[test]
63    fn test_from_url_parse_error() {
64        let url_err: url::ParseError = url::Url::parse("://bad").unwrap_err();
65        let relay_err: RelayError = url_err.into();
66        match relay_err {
67            RelayError::UrlParse(_) => {}
68            other => panic!("Expected UrlParse, got: {other:?}"),
69        }
70    }
71
72    #[test]
73    fn test_from_serde_json_error() {
74        let json_err = serde_json::from_str::<String>("not json").unwrap_err();
75        let relay_err: RelayError = json_err.into();
76        match relay_err {
77            RelayError::SerdeJson(_) => {}
78            other => panic!("Expected SerdeJson, got: {other:?}"),
79        }
80    }
81
82    #[test]
83    fn test_from_core_api_error() {
84        let core_err = polyoxide_core::ApiError::Timeout;
85        let relay_err: RelayError = core_err.into();
86        match relay_err {
87            RelayError::Core(_) => {}
88            other => panic!("Expected Core, got: {other:?}"),
89        }
90    }
91}