1#[derive(Debug, thiserror::Error)]
3pub enum FetchError {
4 #[error("network error: {0}")]
6 Network(String),
7
8 #[error("request timed out after {0:?}")]
10 Timeout(std::time::Duration),
11
12 #[error("HTTP {status}: {body}")]
14 StatusCode {
15 status: u16,
17 body: String,
19 },
20
21 #[error("serialization error: {0}")]
23 Serialization(#[from] serde_json::Error),
24
25 #[error("circuit breaker is open; requests temporarily blocked")]
27 CircuitOpen,
28
29 #[error("middleware error: {0}")]
31 Middleware(String),
32
33 #[error("build error: {0}")]
35 BuildError(String),
36
37 #[error("header error: {0}")]
39 HeaderError(String),
40}
41
42impl From<reqwest::Error> for FetchError {
43 fn from(err: reqwest::Error) -> Self {
44 if err.is_timeout() {
45 FetchError::Timeout(std::time::Duration::ZERO)
49 } else {
50 FetchError::Network(err.to_string())
51 }
52 }
53}
54
55impl From<crate::middleware::Error> for FetchError {
56 fn from(err: crate::middleware::Error) -> Self {
57 match err {
58 crate::middleware::Error::Middleware(e) => {
59 match e.downcast::<FetchError>() {
62 Ok(fetch_err) => *fetch_err,
63 Err(e) => FetchError::Middleware(e.to_string()),
64 }
65 }
66 crate::middleware::Error::Reqwest(e) => FetchError::from(e),
67 }
68 }
69}