dragonfly_client_core/error/
mod.rs

1/*
2 *     Copyright 2024 The Dragonfly Authors
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17pub 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/// DFError is the error for dragonfly.
27#[derive(thiserror::Error, Debug)]
28pub enum DFError {
29    /// IO is the error for IO operation.
30    #[error(transparent)]
31    IO(#[from] std::io::Error),
32
33    /// VarError is the error for environment variable.
34    #[error(transparent)]
35    VarError(#[from] std::env::VarError),
36
37    /// MpscSend is the error for send.
38    #[error("mpsc send: {0}")]
39    MpscSend(String),
40
41    /// SendTimeout is the error for send timeout.
42    #[error("send timeout")]
43    SendTimeout,
44
45    /// HashRing is the error for hashring.
46    #[error{"hashring {0} is failed"}]
47    HashRing(String),
48
49    /// NoSpace is the error when there is no space left on device.
50    #[error("no space left on device: {0}")]
51    NoSpace(String),
52
53    /// HostNotFound is the error when the host is not found.
54    #[error{"host {0} not found"}]
55    HostNotFound(String),
56
57    /// TaskNotFound is the error when the task is not found.
58    #[error{"task {0} not found"}]
59    TaskNotFound(String),
60
61    /// PieceNotFound is the error when the piece is not found.
62    #[error{"piece {0} not found"}]
63    PieceNotFound(String),
64
65    /// PieceStateIsFailed is the error when the piece state is failed.
66    #[error{"piece {0} state is failed"}]
67    PieceStateIsFailed(String),
68
69    /// DownloadPieceFinished is the error when the download piece finished timeout.
70    #[error{"download piece {0} finished timeout"}]
71    DownloadPieceFinishedTimeout(String),
72
73    /// WaitForPieceFinishedTimeout is the error when the wait for piece finished timeout.
74    #[error{"wait for piece {0} finished timeout"}]
75    WaitForPieceFinishedTimeout(String),
76
77    /// AvailableManagerNotFound is the error when the available manager is not found.
78    #[error{"available manager not found"}]
79    AvailableManagerNotFound,
80
81    /// AvailableSchedulersNotFound is the error when the available schedulers is not found.
82    #[error{"available schedulers not found"}]
83    AvailableSchedulersNotFound,
84
85    /// DownloadFromParentFailed is the error when the download from parent is failed.
86    #[error(transparent)]
87    DownloadFromParentFailed(DownloadFromParentFailed),
88
89    /// ColumnFamilyNotFound is the error when the column family is not found.
90    #[error{"column family {0} not found"}]
91    ColumnFamilyNotFound(String),
92
93    /// InvalidStateTransition is the error when the state transition is invalid.
94    #[error{"can not transit from {0} to {1}"}]
95    InvalidStateTransition(String, String),
96
97    /// InvalidState is the error when the state is invalid.
98    #[error{"invalid state {0}"}]
99    InvalidState(String),
100
101    /// InvalidURI is the error when the uri is invalid.
102    #[error("invalid uri {0}")]
103    InvalidURI(String),
104
105    /// InvalidPeer is the error when the peer is invalid.
106    #[error("invalid peer {0}")]
107    InvalidPeer(String),
108
109    /// SchedulerClientNotFound is the error when the scheduler client is not found.
110    #[error{"scheduler client not found"}]
111    SchedulerClientNotFound,
112
113    /// UnexpectedResponse is the error when the response is unexpected.
114    #[error{"unexpected response"}]
115    UnexpectedResponse,
116
117    /// DigestMismatch is the error when the digest is mismatch.
118    #[error{"digest mismatch expected: {0}, actual: {1}"}]
119    DigestMismatch(String, String),
120
121    /// ContentLengthMismatch is the error when the content length is mismatch.
122    #[error("content length mismatch expected: {0}, actual: {1}")]
123    ContentLengthMismatch(u64, u64),
124
125    /// MaxScheduleCountExceeded is the error when the max schedule count is exceeded.
126    #[error("max schedule count {0} exceeded")]
127    MaxScheduleCountExceeded(u32),
128
129    /// InvalidContentLength is the error when the content length is invalid.
130    #[error("invalid content length")]
131    InvalidContentLength,
132
133    /// InvalidPieceLength is the error when the piece length is invalid.
134    #[error("invalid piece length")]
135    InvalidPieceLength,
136
137    /// InvalidParameter is the error when the parameter is invalid.
138    #[error("invalid parameter")]
139    InvalidParameter,
140
141    /// Infallible is the error for infallible.
142    #[error(transparent)]
143    Infallible(#[from] std::convert::Infallible),
144
145    /// Utf8 is the error for utf8.
146    #[error(transparent)]
147    Utf8(#[from] std::str::Utf8Error),
148
149    /// Unknown is the error when the error is unknown.
150    #[error("unknown {0}")]
151    Unknown(String),
152
153    /// Unimplemented is the error when the feature is not implemented.
154    #[error{"unimplemented"}]
155    Unimplemented,
156
157    /// EmptyHTTPRangeError is the error when the range fallback error is empty.
158    #[error{"RangeUnsatisfiable: Failed to parse range fallback error, please file an issue"}]
159    EmptyHTTPRangeError,
160
161    /// Unauthorized is the error for unauthorized.
162    #[error{"unauthorized"}]
163    Unauthorized,
164
165    /// ArrayTryFromSliceError is the error for array try from slice.
166    #[error(transparent)]
167    ArrayTryFromSliceError(#[from] std::array::TryFromSliceError),
168
169    /// VortexProtocolStatus is the error for vortex protocol status.
170    #[error("vortex protocol status: code={0:?}, message={1}")]
171    VortexProtocolStatus(vortex_protocol::tlv::error::Code, String),
172
173    /// VortexProtocolError is the error for vortex protocol.
174    #[error(transparent)]
175    VortexProtocolError(#[from] vortex_protocol::error::Error),
176
177    /// TonicStatus is the error for tonic status.
178    #[error(transparent)]
179    TonicStatus(#[from] tonic::Status),
180
181    /// TonicTransportError is the error for tonic transport.
182    #[error(transparent)]
183    TonicTransportError(#[from] tonic::transport::Error),
184
185    /// TonicReflectionServerError is the error for tonic reflection server.
186    #[error(transparent)]
187    TonicReflectionServerError(#[from] tonic_reflection::server::Error),
188
189    /// TonicStreamElapsed is the error for tonic stream elapsed.
190    #[error(transparent)]
191    TokioStreamElapsed(#[from] tokio_stream::Elapsed),
192
193    // TokioTimeErrorElapsed is the error for tokio time elapsed.
194    #[error(transparent)]
195    TokioTimeErrorElapsed(#[from] tokio::time::error::Elapsed),
196
197    /// HeadersError is the error for headers.
198    #[error(transparent)]
199    HeadersError(#[from] headers::Error),
200
201    // InvalidHeaderName is the error for invalid header name.
202    #[error(transparent)]
203    HTTTHeaderInvalidHeaderName(#[from] http::header::InvalidHeaderName),
204
205    // InvalidHeaderValue is the error for invalid header value.
206    #[error(transparent)]
207    HTTTHeaderInvalidHeaderValue(#[from] http::header::InvalidHeaderValue),
208
209    /// URLParseError is the error for url parse.
210    #[error(transparent)]
211    URLParseError(#[from] url::ParseError),
212
213    /// ReqwestError is the error for reqwest.
214    #[error(transparent)]
215    ReqwestError(#[from] reqwest::Error),
216
217    /// ReqwestMiddlewareError is the error for reqwest middleware.
218    #[error(transparent)]
219    ReqwestMiddlewareError(#[from] reqwest_middleware::Error),
220
221    /// OpenDALError is the error for opendal.
222    #[error(transparent)]
223    OpenDALError(#[from] opendal::Error),
224
225    /// HyperError is the error for hyper.
226    #[error(transparent)]
227    HyperError(#[from] hyper::Error),
228
229    /// BackendError is the error for backend.
230    #[error(transparent)]
231    BackendError(Box<BackendError>),
232
233    /// HyperUtilClientLegacyError is the error for hyper util client legacy.
234    #[error(transparent)]
235    HyperUtilClientLegacyError(#[from] hyper_util::client::legacy::Error),
236
237    /// ExternalError is the error for external error.
238    #[error(transparent)]
239    ExternalError(#[from] ExternalError),
240
241    /// MaxDownloadFilesExceeded is the error for max download files exceeded.
242    #[error("max number of files to download exceeded: {0}")]
243    MaxDownloadFilesExceeded(usize),
244
245    /// Unsupported is the error for unsupported.
246    #[error("unsupported {0}")]
247    Unsupported(String),
248
249    /// TokioJoinError is the error for tokio join.
250    #[error(transparent)]
251    TokioJoinError(tokio::task::JoinError),
252
253    /// ValidationError is the error for validate.
254    #[error("validate failed: {0}")]
255    ValidationError(String),
256}
257
258/// SendError is the error for send.
259impl<T> From<tokio::sync::mpsc::error::SendError<T>> for DFError {
260    fn from(e: tokio::sync::mpsc::error::SendError<T>) -> Self {
261        Self::MpscSend(e.to_string())
262    }
263}
264
265/// SendTimeoutError is the error for send timeout.
266impl<T> From<tokio::sync::mpsc::error::SendTimeoutError<T>> for DFError {
267    fn from(err: tokio::sync::mpsc::error::SendTimeoutError<T>) -> Self {
268        match err {
269            tokio::sync::mpsc::error::SendTimeoutError::Timeout(_) => Self::SendTimeout,
270            tokio::sync::mpsc::error::SendTimeoutError::Closed(_) => Self::SendTimeout,
271        }
272    }
273}
274
275#[cfg(test)]
276mod tests {
277    use super::*;
278
279    #[test]
280    fn should_convert_externalerror_to_dferror() {
281        fn function_return_inner_error() -> Result<(), std::io::Error> {
282            let inner_error = std::io::Error::new(std::io::ErrorKind::Other, "inner error");
283            Err(inner_error)
284        }
285
286        fn do_sth_with_error() -> Result<(), DFError> {
287            function_return_inner_error().map_err(|err| {
288                ExternalError::new(crate::error::ErrorType::StorageError).with_cause(err.into())
289            })?;
290            Ok(())
291        }
292
293        let err = do_sth_with_error().err().unwrap();
294        assert_eq!(format!("{}", err), "StorageError cause: inner error");
295    }
296}