Skip to main content

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    /// NetAddrParseError is the error for net address parse.
142    #[error(transparent)]
143    NetAddrParseError(#[from] std::net::AddrParseError),
144
145    /// ConvertInfallible is the error for infallible.
146    #[error(transparent)]
147    ConvertInfallible(#[from] std::convert::Infallible),
148
149    /// Utf8 is the error for utf8.
150    #[error(transparent)]
151    Utf8(#[from] std::str::Utf8Error),
152
153    /// Unknown is the error when the error is unknown.
154    #[error("unknown {0}")]
155    Unknown(String),
156
157    /// Unimplemented is the error when the feature is not implemented.
158    #[error{"unimplemented"}]
159    Unimplemented,
160
161    /// EmptyHTTPRangeError is the error when the range fallback error is empty.
162    #[error{"RangeUnsatisfiable: Failed to parse range fallback error, please file an issue"}]
163    EmptyHTTPRangeError,
164
165    /// Unauthorized is the error for unauthorized.
166    #[error{"unauthorized"}]
167    Unauthorized,
168
169    /// ArrayTryFromSliceError is the error for array try from slice.
170    #[error(transparent)]
171    ArrayTryFromSliceError(#[from] std::array::TryFromSliceError),
172
173    /// VortexProtocolStatus is the error for vortex protocol status.
174    #[error("vortex protocol status: code={0:?}, message={1}")]
175    VortexProtocolStatus(vortex_protocol::tlv::error::Code, String),
176
177    /// VortexProtocolError is the error for vortex protocol.
178    #[error(transparent)]
179    VortexProtocolError(#[from] vortex_protocol::error::Error),
180
181    /// TonicStatus is the error for tonic status.
182    #[error(transparent)]
183    TonicStatus(#[from] tonic::Status),
184
185    /// TonicTransportError is the error for tonic transport.
186    #[error(transparent)]
187    TonicTransportError(#[from] tonic::transport::Error),
188
189    /// TonicReflectionServerError is the error for tonic reflection server.
190    #[error(transparent)]
191    TonicReflectionServerError(#[from] tonic_reflection::server::Error),
192
193    /// TonicStreamElapsed is the error for tonic stream elapsed.
194    #[error(transparent)]
195    TokioStreamElapsed(#[from] tokio_stream::Elapsed),
196
197    // TokioTimeErrorElapsed is the error for tokio time elapsed.
198    #[error(transparent)]
199    TokioTimeErrorElapsed(#[from] tokio::time::error::Elapsed),
200
201    /// HeadersError is the error for headers.
202    #[error(transparent)]
203    HeadersError(#[from] headers::Error),
204
205    // InvalidHeaderName is the error for invalid header name.
206    #[error(transparent)]
207    HTTTHeaderInvalidHeaderName(#[from] http::header::InvalidHeaderName),
208
209    // InvalidHeaderValue is the error for invalid header value.
210    #[error(transparent)]
211    HTTTHeaderInvalidHeaderValue(#[from] http::header::InvalidHeaderValue),
212
213    // HTTTHeaderToStrError is the error for header to str.
214    #[error(transparent)]
215    HTTTHeaderToStrError(#[from] http::header::ToStrError),
216
217    /// URLParseError is the error for url parse.
218    #[error(transparent)]
219    URLParseError(#[from] url::ParseError),
220
221    /// ReqwestError is the error for reqwest.
222    #[error(transparent)]
223    ReqwestError(#[from] reqwest::Error),
224
225    /// ReqwestMiddlewareError is the error for reqwest middleware.
226    #[error(transparent)]
227    ReqwestMiddlewareError(#[from] reqwest_middleware::Error),
228
229    /// OpenDALError is the error for opendal.
230    #[error(transparent)]
231    OpenDALError(#[from] opendal::Error),
232
233    /// HyperError is the error for hyper.
234    #[error(transparent)]
235    HyperError(#[from] hyper::Error),
236
237    /// BackendError is the error for backend.
238    #[error(transparent)]
239    BackendError(Box<BackendError>),
240
241    /// HyperUtilClientLegacyError is the error for hyper util client legacy.
242    #[error(transparent)]
243    HyperUtilClientLegacyError(#[from] hyper_util::client::legacy::Error),
244
245    /// ExternalError is the error for external error.
246    #[error(transparent)]
247    ExternalError(#[from] ExternalError),
248
249    /// MaxDownloadFilesExceeded is the error for max download files exceeded.
250    #[error(
251        "exceeded the maximum download limit of {0} files. Use --max-files to increase this limit"
252    )]
253    MaxDownloadFilesExceeded(usize),
254
255    /// Unsupported is the error for unsupported.
256    #[error("unsupported {0}")]
257    Unsupported(String),
258
259    /// TokioJoinError is the error for tokio join.
260    #[error(transparent)]
261    TokioJoinError(tokio::task::JoinError),
262
263    /// ValidationError is the error for validate.
264    #[error("validate failed: {0}")]
265    ValidationError(String),
266
267    /// CgroupsFSError is the error for cgroups fs.
268    #[cfg(target_os = "linux")]
269    #[error(transparent)]
270    CgroupsFSError(#[from] cgroups_rs::fs::error::Error),
271}
272
273/// SendError is the error for send.
274impl<T> From<tokio::sync::mpsc::error::SendError<T>> for DFError {
275    fn from(e: tokio::sync::mpsc::error::SendError<T>) -> Self {
276        Self::MpscSend(e.to_string())
277    }
278}
279
280/// SendTimeoutError is the error for send timeout.
281impl<T> From<tokio::sync::mpsc::error::SendTimeoutError<T>> for DFError {
282    fn from(err: tokio::sync::mpsc::error::SendTimeoutError<T>) -> Self {
283        match err {
284            tokio::sync::mpsc::error::SendTimeoutError::Timeout(_) => Self::SendTimeout,
285            tokio::sync::mpsc::error::SendTimeoutError::Closed(_) => Self::SendTimeout,
286        }
287    }
288}
289
290#[cfg(test)]
291mod tests {
292    use super::*;
293
294    #[test]
295    fn should_convert_externalerror_to_dferror() {
296        fn function_return_inner_error() -> Result<(), std::io::Error> {
297            let inner_error = std::io::Error::new(std::io::ErrorKind::Other, "inner error");
298            Err(inner_error)
299        }
300
301        fn do_sth_with_error() -> Result<(), DFError> {
302            function_return_inner_error().map_err(|err| {
303                ExternalError::new(crate::error::ErrorType::StorageError).with_cause(err.into())
304            })?;
305            Ok(())
306        }
307
308        let err = do_sth_with_error().err().unwrap();
309        assert_eq!(format!("{}", err), "StorageError cause: inner error");
310    }
311}