1use thiserror::Error;
4
5use crate::request::JsonRpcError;
6
7#[derive(Debug, Error)]
9pub enum TransportError {
10 #[error("HTTP error: {0}")]
12 Http(String),
13
14 #[error("WebSocket error: {0}")]
16 WebSocket(String),
17
18 #[error("RPC error {}: {}", .0.code, .0.message)]
20 Rpc(JsonRpcError),
21
22 #[error("Rate limit exceeded (provider: {provider})")]
24 RateLimited { provider: String },
25
26 #[error("Circuit breaker open for provider: {provider}")]
28 CircuitOpen { provider: String },
29
30 #[error("All providers unavailable")]
32 AllProvidersDown,
33
34 #[error("Request timed out after {ms}ms")]
36 Timeout { ms: u64 },
37
38 #[error("Deserialization error: {0}")]
40 Deserialization(#[from] serde_json::Error),
41
42 #[error("Transport overloaded ({queue_depth} requests in flight)")]
44 Overloaded { queue_depth: usize },
45
46 #[error("Operation cancelled")]
48 Cancelled,
49
50 #[error("{0}")]
52 Other(String),
53}
54
55impl TransportError {
56 pub fn is_retryable(&self) -> bool {
58 matches!(
59 self,
60 Self::Http(_) | Self::WebSocket(_) | Self::Timeout { .. } | Self::RateLimited { .. }
61 )
62 }
63
64 pub fn is_execution_error(&self) -> bool {
66 matches!(self, Self::Rpc(_))
67 }
68}