fedimint_connectors/
error.rs1use fedimint_core::PeerId;
2use fedimint_core::util::SafeUrl;
3use fedimint_logging::LOG_CLIENT_NET_API;
4use thiserror::Error;
5use tracing::{trace, warn};
6
7#[derive(Debug, Error)]
12#[non_exhaustive]
13pub enum ConnectorError {
14 #[error("Unsupported scheme {scheme}; missing endpoint handler")]
16 UnsupportedScheme { scheme: String },
17
18 #[error("The {scheme} connector is not enabled")]
21 NotEnabled { scheme: &'static str },
22
23 #[error("Tor was requested, but support for it is not compiled in")]
25 TorNotCompiledIn,
26
27 #[error("This transport cannot connect to a gateway")]
29 GatewayUnsupported,
30
31 #[error("Missing host in url {url}")]
33 MissingHost { url: SafeUrl },
34
35 #[error("Invalid Iroh node id {host}")]
37 InvalidNodeId {
38 host: String,
39 #[source]
40 source: Box<dyn std::error::Error + Send + Sync>,
41 },
42
43 #[error("Invalid url {url}")]
45 InvalidUrl {
46 url: String,
47 #[source]
48 source: Box<dyn std::error::Error + Send + Sync>,
49 },
50
51 #[error("Unsupported Iroh api url path {path}")]
53 UnsupportedUrlPath { path: String },
54
55 #[error("Transport failure")]
57 Transport(#[source] Box<dyn std::error::Error + Send + Sync>),
58
59 #[error("Failed to bootstrap the Tor client")]
61 Tor(#[source] Box<dyn std::error::Error + Send + Sync>),
62}
63
64#[derive(Debug, Error)]
66#[non_exhaustive]
67pub enum ServerError {
68 #[error("Response deserialization error: {0}")]
71 ResponseDeserialization(Box<dyn std::error::Error + Send + Sync>),
72
73 #[error("Invalid peer id: {peer_id}")]
75 InvalidPeerId { peer_id: PeerId },
76
77 #[error("Invalid peer url: {url}")]
81 InvalidPeerUrl {
82 url: SafeUrl,
83 source: Box<ConnectorError>,
84 },
85
86 #[error("Invalid endpoint: {0}")]
88 InvalidEndpoint(Box<dyn std::error::Error + Send + Sync>),
89
90 #[error("Connection failed: {0}")]
92 Connection(Box<dyn std::error::Error + Send + Sync>),
93
94 #[error("Transport error: {0}")]
96 Transport(Box<dyn std::error::Error + Send + Sync>),
97
98 #[error("Invalid rpc id: {0}")]
104 InvalidRpcId(String),
105
106 #[error("Invalid request: {0}")]
109 InvalidRequest(String),
110
111 #[error("Invalid response: {0}")]
113 InvalidResponse(String),
114
115 #[error("Unspecified server error: {0}")]
117 ServerError(String),
118
119 #[error("Unspecified condition error: {0}")]
124 ConditionFailed(String),
125
126 #[error("Unspecified internal client error: {0}")]
131 InternalClientError(String),
132}
133
134impl ServerError {
135 pub fn is_unusual(&self) -> bool {
136 match self {
137 ServerError::ResponseDeserialization(_)
138 | ServerError::InvalidPeerId { .. }
139 | ServerError::InvalidPeerUrl { .. }
140 | ServerError::InvalidResponse(_)
141 | ServerError::InvalidRpcId(_)
142 | ServerError::InvalidRequest(_)
143 | ServerError::InternalClientError(_)
144 | ServerError::InvalidEndpoint(_)
145 | ServerError::ServerError(_) => true,
146 ServerError::Connection(_)
147 | ServerError::Transport(_)
148 | ServerError::ConditionFailed(_) => false,
149 }
150 }
151 pub fn report_if_unusual(&self, peer_id: PeerId, context: &str) {
157 let unusual = self.is_unusual();
158
159 trace!(target: LOG_CLIENT_NET_API, error = %self, %context, "ServerError");
160
161 if unusual {
162 warn!(target: LOG_CLIENT_NET_API, error = %self,%context, %peer_id, "Unusual ServerError");
163 }
164 }
165}