coinbase_advanced/
error.rs1use std::time::Duration;
2
3pub type Result<T> = std::result::Result<T, Error>;
5
6#[derive(Debug, thiserror::Error)]
8pub enum Error {
9 #[error("Configuration error: {0}")]
11 Config(String),
12
13 #[error("JWT error: {0}")]
15 Jwt(String),
16
17 #[error("HTTP error: {0}")]
19 Http(#[from] reqwest::Error),
20
21 #[error("Request error: {0}")]
23 Request(String),
24
25 #[error("API error: {message}")]
27 Api {
28 message: String,
30 status: u16,
32 body: Option<String>,
34 },
35
36 #[error("Rate limited, retry after {retry_after:?}")]
38 RateLimited {
39 retry_after: Option<Duration>,
41 },
42
43 #[error("Parse error: {message}")]
45 Parse {
46 message: String,
48 body: Option<String>,
50 },
51
52 #[error("Authentication error: {0}")]
54 Auth(String),
55
56 #[error("URL error: {0}")]
58 Url(#[from] url::ParseError),
59
60 #[error("WebSocket error: {0}")]
62 WebSocket(String),
63}
64
65impl Error {
66 pub fn config(msg: impl Into<String>) -> Self {
68 Self::Config(msg.into())
69 }
70
71 pub fn jwt(msg: impl Into<String>) -> Self {
73 Self::Jwt(msg.into())
74 }
75
76 pub fn request(msg: impl Into<String>) -> Self {
78 Self::Request(msg.into())
79 }
80
81 pub fn api(status: u16, message: impl Into<String>, body: Option<String>) -> Self {
83 Self::Api {
84 message: message.into(),
85 status,
86 body,
87 }
88 }
89
90 pub fn parse(message: impl Into<String>, body: Option<String>) -> Self {
92 Self::Parse {
93 message: message.into(),
94 body,
95 }
96 }
97
98 pub fn auth(msg: impl Into<String>) -> Self {
100 Self::Auth(msg.into())
101 }
102
103 pub fn websocket(msg: impl Into<String>) -> Self {
105 Self::WebSocket(msg.into())
106 }
107
108 pub fn is_rate_limited(&self) -> bool {
110 matches!(self, Self::RateLimited { .. })
111 }
112
113 pub fn is_retryable(&self) -> bool {
115 match self {
116 Self::RateLimited { .. } => true,
117 Self::Http(e) => e.is_timeout() || e.is_connect(),
118 Self::Api { status, .. } => *status >= 500,
119 _ => false,
120 }
121 }
122}