1use std::fmt;
4
5#[derive(Debug, thiserror::Error)]
7pub enum Error {
8 #[error("all providers failed: {0:?}")]
10 AllProvidersFailed(Vec<ProviderError>),
11
12 #[error("operation timed out")]
14 Timeout,
15
16 #[error("no providers configured")]
18 NoProviders,
19
20 #[error("no providers support the requested IP version")]
22 NoProvidersForVersion,
23
24 #[error("consensus could not be reached (required {required}, got {got})")]
26 ConsensusNotReached {
27 required: usize,
29 got: usize,
31 },
32}
33
34#[derive(Debug)]
36pub struct ProviderError {
37 pub provider: String,
39 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 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 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 {}