Skip to main content

ip_discovery/
error.rs

1//! Error types for ip-discovery
2
3use std::fmt;
4
5/// Main error type for IP detection
6#[derive(Debug, thiserror::Error)]
7pub enum Error {
8    /// All configured providers failed
9    #[error("all providers failed: {0:?}")]
10    AllProvidersFailed(Vec<ProviderError>),
11
12    /// Operation timed out
13    #[error("operation timed out")]
14    Timeout,
15
16    /// No providers configured
17    #[error("no providers configured")]
18    NoProviders,
19
20    /// No providers support the requested IP version
21    #[error("no providers support the requested IP version")]
22    NoProvidersForVersion,
23
24    /// Consensus could not be reached
25    #[error("consensus could not be reached (required {required}, got {got})")]
26    ConsensusNotReached {
27        /// Minimum number of providers that needed to agree
28        required: usize,
29        /// Number of providers that actually agreed
30        got: usize,
31    },
32}
33
34/// Error from a specific provider
35#[derive(Debug)]
36pub struct ProviderError {
37    /// Name of the provider that failed
38    pub provider: String,
39    /// The error that occurred
40    pub error: Box<dyn std::error::Error + Send + Sync>,
41}
42
43impl fmt::Display for ProviderError {
44    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
45        write!(f, "{}: {}", self.provider, self.error)
46    }
47}
48
49impl std::error::Error for ProviderError {
50    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
51        Some(self.error.as_ref())
52    }
53}
54
55impl ProviderError {
56    /// Create a new provider error from any error type.
57    pub fn new<E>(provider: impl Into<String>, error: E) -> Self
58    where
59        E: std::error::Error + Send + Sync + 'static,
60    {
61        Self {
62            provider: provider.into(),
63            error: Box::new(error),
64        }
65    }
66
67    /// Create a new provider error from a message string.
68    pub fn message(provider: impl Into<String>, msg: impl Into<String>) -> Self {
69        Self {
70            provider: provider.into(),
71            error: Box::new(StringError(msg.into())),
72        }
73    }
74}
75
76#[derive(Debug)]
77struct StringError(String);
78
79impl fmt::Display for StringError {
80    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
81        write!(f, "{}", self.0)
82    }
83}
84
85impl std::error::Error for StringError {}