1use crate::error_code::ErrorCode;
16use reqwest::StatusCode;
17
18#[derive(Debug)]
19pub enum Error {
20 WithContext(Box<Error>, String),
21
22 BadArgument(String),
25 IO(String),
29
30 Request(String),
32
33 Decode(String),
37
38 QueryFailed(ErrorCode),
40
41 Logic(StatusCode, ErrorCode),
43
44 Response {
46 status: StatusCode,
47 msg: String,
48 },
49
50 QueryNotFound(String),
60 AuthFailure(ErrorCode),
61}
62
63impl Error {
64 pub fn response_error(status: StatusCode, body: &[u8]) -> Self {
65 Self::Response {
66 status,
67 msg: String::from_utf8_lossy(body).to_string(),
68 }
69 }
70
71 pub fn with_context(self, ctx: &str) -> Self {
72 Error::WithContext(Box::new(self), ctx.to_string())
73 }
74
75 pub fn status_code(&self) -> Option<StatusCode> {
76 match self {
77 Error::Logic(status, ..) => Some(*status),
78 Error::Response { status, .. } => Some(*status),
79 Error::WithContext(err, _) => err.status_code(),
80 _ => None,
81 }
82 }
83}
84
85impl std::fmt::Display for Error {
86 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
87 match self {
88 Error::Decode(msg) => write!(f, "DecodeError: {msg}"),
89 Error::BadArgument(msg) => write!(f, "BadArgument: {msg}"),
90 Error::Request(msg) => write!(f, "{msg}"),
91 Error::Response { msg, status } => write!(f, "ResponseError: ({status}){msg}"),
92 Error::IO(msg) => write!(f, "IOError: {msg}"),
93 Error::Logic(status_code, ec) => write!(f, "BadRequest:({status_code}){ec}"),
94 Error::QueryNotFound(msg) => write!(f, "QueryNotFound: {msg}"),
95 Error::QueryFailed(ec) => write!(f, "QueryFailed: {ec}"),
96 Error::AuthFailure(ec) => write!(f, "AuthFailure: {ec}"),
97
98 Error::WithContext(err, ctx) => write!(f, "fail to {ctx}: {err}"),
99 }
100 }
101}
102
103impl std::error::Error for Error {}
104
105pub type Result<T, E = Error> = core::result::Result<T, E>;
106
107impl From<url::ParseError> for Error {
108 fn from(e: url::ParseError) -> Self {
109 Error::Decode(e.to_string())
110 }
111}
112
113impl From<std::num::ParseIntError> for Error {
114 fn from(e: std::num::ParseIntError) -> Self {
115 Error::Decode(e.to_string())
116 }
117}
118
119impl From<reqwest::header::InvalidHeaderValue> for Error {
121 fn from(e: reqwest::header::InvalidHeaderValue) -> Self {
122 Error::BadArgument(e.to_string())
123 }
124}
125
126impl From<serde_json::Error> for Error {
127 fn from(e: serde_json::Error) -> Self {
128 Error::Decode(e.to_string())
129 }
130}
131
132impl From<reqwest::Error> for Error {
133 fn from(e: reqwest::Error) -> Self {
134 Error::Request(e.to_string())
135 }
136}
137
138impl From<std::io::Error> for Error {
139 fn from(e: std::io::Error) -> Self {
140 Error::IO(e.to_string())
141 }
142}
143
144impl From<std::str::Utf8Error> for Error {
145 fn from(e: std::str::Utf8Error) -> Self {
146 Error::Decode(e.to_string())
147 }
148}