dragonfly_client_core/error/
mod.rs1pub mod errors;
18pub mod message;
19
20pub use errors::ErrorType;
21pub use errors::ExternalError;
22
23pub use errors::OrErr;
24pub use errors::{BackendError, DownloadFromParentFailed};
25
26#[derive(thiserror::Error, Debug)]
28pub enum DFError {
29 #[error(transparent)]
31 IO(#[from] std::io::Error),
32
33 #[error("mpsc send: {0}")]
35 MpscSend(String),
36
37 #[error("send timeout")]
39 SendTimeout,
40
41 #[error{"hashring {0} is failed"}]
43 HashRing(String),
44
45 #[error("no space left on device: {0}")]
47 NoSpace(String),
48
49 #[error{"host {0} not found"}]
51 HostNotFound(String),
52
53 #[error{"task {0} not found"}]
55 TaskNotFound(String),
56
57 #[error{"piece {0} not found"}]
59 PieceNotFound(String),
60
61 #[error{"piece {0} state is failed"}]
63 PieceStateIsFailed(String),
64
65 #[error{"download piece {0} finished timeout"}]
67 DownloadPieceFinishedTimeout(String),
68
69 #[error{"wait for piece {0} finished timeout"}]
71 WaitForPieceFinishedTimeout(String),
72
73 #[error{"available manager not found"}]
75 AvailableManagerNotFound,
76
77 #[error{"available schedulers not found"}]
79 AvailableSchedulersNotFound,
80
81 #[error(transparent)]
83 DownloadFromParentFailed(DownloadFromParentFailed),
84
85 #[error{"column family {0} not found"}]
87 ColumnFamilyNotFound(String),
88
89 #[error{"can not transit from {0} to {1}"}]
91 InvalidStateTransition(String, String),
92
93 #[error{"invalid state {0}"}]
95 InvalidState(String),
96
97 #[error("invalid uri {0}")]
99 InvalidURI(String),
100
101 #[error("invalid peer {0}")]
103 InvalidPeer(String),
104
105 #[error{"scheduler client not found"}]
107 SchedulerClientNotFound,
108
109 #[error{"unexpected response"}]
111 UnexpectedResponse,
112
113 #[error{"digest mismatch expected: {0}, actual: {1}"}]
115 DigestMismatch(String, String),
116
117 #[error("content length mismatch expected: {0}, actual: {1}")]
119 ContentLengthMismatch(u64, u64),
120
121 #[error("max schedule count {0} exceeded")]
123 MaxScheduleCountExceeded(u32),
124
125 #[error("invalid content length")]
127 InvalidContentLength,
128
129 #[error("invalid piece length")]
131 InvalidPieceLength,
132
133 #[error("invalid parameter")]
135 InvalidParameter,
136
137 #[error(transparent)]
139 Infallible(#[from] std::convert::Infallible),
140
141 #[error(transparent)]
143 Utf8(#[from] std::str::Utf8Error),
144
145 #[error("unknown {0}")]
147 Unknown(String),
148
149 #[error{"unimplemented"}]
151 Unimplemented,
152
153 #[error{"RangeUnsatisfiable: Failed to parse range fallback error, please file an issue"}]
155 EmptyHTTPRangeError,
156
157 #[error{"unauthorized"}]
159 Unauthorized,
160
161 #[error(transparent)]
163 ArrayTryFromSliceError(#[from] std::array::TryFromSliceError),
164
165 #[error("vortex protocol status: code={0:?}, message={1}")]
167 VortexProtocolStatus(vortex_protocol::tlv::error::Code, String),
168
169 #[error(transparent)]
171 VortexProtocolError(#[from] vortex_protocol::error::Error),
172
173 #[error(transparent)]
175 TonicStatus(#[from] tonic::Status),
176
177 #[error(transparent)]
179 TonicTransportError(#[from] tonic::transport::Error),
180
181 #[error(transparent)]
183 TonicReflectionServerError(#[from] tonic_reflection::server::Error),
184
185 #[error(transparent)]
187 TokioStreamElapsed(#[from] tokio_stream::Elapsed),
188
189 #[error(transparent)]
191 TokioTimeErrorElapsed(#[from] tokio::time::error::Elapsed),
192
193 #[error(transparent)]
195 HeadersError(#[from] headers::Error),
196
197 #[error(transparent)]
199 HTTTHeaderInvalidHeaderName(#[from] http::header::InvalidHeaderName),
200
201 #[error(transparent)]
203 HTTTHeaderInvalidHeaderValue(#[from] http::header::InvalidHeaderValue),
204
205 #[error(transparent)]
207 URLParseError(#[from] url::ParseError),
208
209 #[error(transparent)]
211 ReqwestError(#[from] reqwest::Error),
212
213 #[error(transparent)]
215 ReqwestMiddlewareError(#[from] reqwest_middleware::Error),
216
217 #[error(transparent)]
219 OpenDALError(#[from] opendal::Error),
220
221 #[error(transparent)]
223 HyperError(#[from] hyper::Error),
224
225 #[error(transparent)]
227 BackendError(Box<BackendError>),
228
229 #[error(transparent)]
231 HyperUtilClientLegacyError(#[from] hyper_util::client::legacy::Error),
232
233 #[error(transparent)]
235 ExternalError(#[from] ExternalError),
236
237 #[error("max number of files to download exceeded: {0}")]
239 MaxDownloadFilesExceeded(usize),
240
241 #[error("unsupported {0}")]
243 Unsupported(String),
244
245 #[error(transparent)]
247 TokioJoinError(tokio::task::JoinError),
248
249 #[error("validate failed: {0}")]
251 ValidationError(String),
252}
253
254impl<T> From<tokio::sync::mpsc::error::SendError<T>> for DFError {
256 fn from(e: tokio::sync::mpsc::error::SendError<T>) -> Self {
257 Self::MpscSend(e.to_string())
258 }
259}
260
261impl<T> From<tokio::sync::mpsc::error::SendTimeoutError<T>> for DFError {
263 fn from(err: tokio::sync::mpsc::error::SendTimeoutError<T>) -> Self {
264 match err {
265 tokio::sync::mpsc::error::SendTimeoutError::Timeout(_) => Self::SendTimeout,
266 tokio::sync::mpsc::error::SendTimeoutError::Closed(_) => Self::SendTimeout,
267 }
268 }
269}
270
271#[cfg(test)]
272mod tests {
273 use super::*;
274
275 #[test]
276 fn should_convert_externalerror_to_dferror() {
277 fn function_return_inner_error() -> Result<(), std::io::Error> {
278 let inner_error = std::io::Error::new(std::io::ErrorKind::Other, "inner error");
279 Err(inner_error)
280 }
281
282 fn do_sth_with_error() -> Result<(), DFError> {
283 function_return_inner_error().map_err(|err| {
284 ExternalError::new(crate::error::ErrorType::StorageError).with_cause(err.into())
285 })?;
286 Ok(())
287 }
288
289 let err = do_sth_with_error().err().unwrap();
290 assert_eq!(format!("{}", err), "StorageError cause: inner error");
291 }
292}