1use reqwest::StatusCode;
7use std::io;
8
9#[derive(Debug, thiserror::Error)]
11pub enum FetchError {
12 #[error("network error: {0}")]
14 Reqwest(#[from] reqwest::Error),
15 #[error("db error: {0}")]
17 Sqlx(#[from] sqlx::Error),
18 #[error("parser error: {0}")]
20 Parser(String),
21}
22
23#[derive(Debug, thiserror::Error)]
25pub enum AuthError {
26 #[error("network error: {0}")]
28 Network(#[from] reqwest::Error),
29 #[error("io error: {0}")]
31 Io(#[from] io::Error),
32 #[error("json error: {0}")]
34 Json(#[from] serde_json::Error),
35 #[error("other error: {0}")]
37 Other(String),
38 #[error("bad credentials")]
40 BadCredentials,
41 #[error("unexpected http status: {0}")]
43 Unexpected(StatusCode),
44 #[error("rate limit exceeded")]
46 RateLimitExceeded,
47}
48
49impl From<Box<dyn std::error::Error + Send + Sync>> for AuthError {
50 #[cold]
51 fn from(e: Box<dyn std::error::Error + Send + Sync>) -> Self {
52 match e.downcast::<reqwest::Error>() {
53 Ok(req) => AuthError::Network(*req),
54 Err(e) => match e.downcast::<serde_json::Error>() {
55 Ok(js) => AuthError::Json(*js),
56 Err(e) => match e.downcast::<std::io::Error>() {
57 Ok(ioe) => AuthError::Io(*ioe),
58 Err(other) => AuthError::Other(other.to_string()),
59 },
60 },
61 }
62 }
63}
64
65impl From<Box<dyn std::error::Error>> for AuthError {
66 #[cold]
67 fn from(e: Box<dyn std::error::Error>) -> Self {
68 match e.downcast::<reqwest::Error>() {
69 Ok(req) => AuthError::Network(*req),
70 Err(e) => match e.downcast::<serde_json::Error>() {
71 Ok(js) => AuthError::Json(*js),
72 Err(e) => match e.downcast::<io::Error>() {
73 Ok(ioe) => AuthError::Io(*ioe),
74 Err(other) => AuthError::Other(other.to_string()),
75 },
76 },
77 }
78 }
79}
80
81impl From<AppError> for AuthError {
82 #[cold]
83 fn from(e: AppError) -> Self {
84 match e {
85 AppError::Network(e) => AuthError::Network(e),
86 AppError::Io(e) => AuthError::Io(e),
87 AppError::Json(e) => AuthError::Json(e),
88 AppError::Unexpected(s) => AuthError::Unexpected(s),
89 _ => AuthError::Other(e.to_string()),
90 }
91 }
92}
93
94#[derive(Debug, thiserror::Error)]
96pub enum AppError {
97 #[error("network error: {0}")]
99 Network(#[from] reqwest::Error),
100 #[error("io error: {0}")]
102 Io(#[from] io::Error),
103 #[error("json error: {0}")]
105 Json(#[from] serde_json::Error),
106 #[error("unexpected http status: {0}")]
108 Unexpected(StatusCode),
109 #[error("db error: {0}")]
111 Db(#[from] sqlx::Error),
112 #[error("unauthorized")]
114 Unauthorized,
115 #[error("oauth token expired")]
117 OAuthTokenExpired,
118 #[error("not found")]
120 NotFound,
121 #[error("rate limit exceeded")]
123 RateLimitExceeded,
124 #[error("historical data allowance exceeded, resets in {allowance_expiry} seconds")]
129 HistoricalDataAllowanceExceeded {
130 allowance_expiry: u64,
132 },
133 #[error("serialization error: {0}")]
135 SerializationError(String),
136 #[error("websocket error: {0}")]
138 WebSocketError(String),
139 #[error("deserialization error: {0}")]
141 Deserialization(String),
142 #[error("invalid input: {0}")]
144 InvalidInput(String),
145 #[error("generic error: {0}")]
147 Generic(String),
148}
149
150impl From<AuthError> for AppError {
151 #[cold]
152 fn from(e: AuthError) -> Self {
153 match e {
154 AuthError::Network(e) => AppError::Network(e),
155 AuthError::Io(e) => AppError::Io(e),
156 AuthError::Json(e) => AppError::Json(e),
157 AuthError::BadCredentials => AppError::Unauthorized,
158 AuthError::Unexpected(s) => AppError::Unexpected(s),
159 _ => AppError::Unexpected(StatusCode::INTERNAL_SERVER_ERROR),
160 }
161 }
162}
163
164impl From<Box<dyn std::error::Error>> for AppError {
165 #[cold]
166 fn from(e: Box<dyn std::error::Error>) -> Self {
167 match e.downcast::<reqwest::Error>() {
168 Ok(req) => AppError::Network(*req),
169 Err(e) => match e.downcast::<serde_json::Error>() {
170 Ok(js) => AppError::Json(*js),
171 Err(e) => match e.downcast::<std::io::Error>() {
172 Ok(ioe) => AppError::Io(*ioe),
173 Err(_) => AppError::Unexpected(StatusCode::INTERNAL_SERVER_ERROR),
174 },
175 },
176 }
177 }
178}
179
180impl From<String> for AppError {
181 #[cold]
182 fn from(e: String) -> Self {
183 AppError::Generic(e)
184 }
185}
186
187impl From<lightstreamer_rs::utils::LightstreamerError> for AppError {
188 #[cold]
189 fn from(e: lightstreamer_rs::utils::LightstreamerError) -> Self {
190 AppError::WebSocketError(e.to_string())
191 }
192}