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    /// MpscSend is the error for send.
34    #[error("mpsc send: {0}")]
35    MpscSend(String),
36
37    /// SendTimeout is the error for send timeout.
38    #[error("send timeout")]
39    SendTimeout,
40
41    /// HashRing is the error for hashring.
42    #[error{"hashring {0} is failed"}]
43    HashRing(String),
44
45    /// NoSpace is the error when there is no space left on device.
46    #[error("no space left on device: {0}")]
47    NoSpace(String),
48
49    /// HostNotFound is the error when the host is not found.
50    #[error{"host {0} not found"}]
51    HostNotFound(String),
52
53    /// TaskNotFound is the error when the task is not found.
54    #[error{"task {0} not found"}]
55    TaskNotFound(String),
56
57    /// PieceNotFound is the error when the piece is not found.
58    #[error{"piece {0} not found"}]
59    PieceNotFound(String),
60
61    /// PieceStateIsFailed is the error when the piece state is failed.
62    #[error{"piece {0} state is failed"}]
63    PieceStateIsFailed(String),
64
65    /// DownloadPieceFinished is the error when the download piece finished timeout.
66    #[error{"download piece {0} finished timeout"}]
67    DownloadPieceFinishedTimeout(String),
68
69    /// WaitForPieceFinishedTimeout is the error when the wait for piece finished timeout.
70    #[error{"wait for piece {0} finished timeout"}]
71    WaitForPieceFinishedTimeout(String),
72
73    /// AvailableManagerNotFound is the error when the available manager is not found.
74    #[error{"available manager not found"}]
75    AvailableManagerNotFound,
76
77    /// AvailableSchedulersNotFound is the error when the available schedulers is not found.
78    #[error{"available schedulers not found"}]
79    AvailableSchedulersNotFound,
80
81    /// DownloadFromParentFailed is the error when the download from parent is failed.
82    #[error(transparent)]
83    DownloadFromParentFailed(DownloadFromParentFailed),
84
85    /// ColumnFamilyNotFound is the error when the column family is not found.
86    #[error{"column family {0} not found"}]
87    ColumnFamilyNotFound(String),
88
89    /// InvalidStateTransition is the error when the state transition is invalid.
90    #[error{"can not transit from {0} to {1}"}]
91    InvalidStateTransition(String, String),
92
93    /// InvalidState is the error when the state is invalid.
94    #[error{"invalid state {0}"}]
95    InvalidState(String),
96
97    /// InvalidURI is the error when the uri is invalid.
98    #[error("invalid uri {0}")]
99    InvalidURI(String),
100
101    /// InvalidPeer is the error when the peer is invalid.
102    #[error("invalid peer {0}")]
103    InvalidPeer(String),
104
105    /// SchedulerClientNotFound is the error when the scheduler client is not found.
106    #[error{"scheduler client not found"}]
107    SchedulerClientNotFound,
108
109    /// UnexpectedResponse is the error when the response is unexpected.
110    #[error{"unexpected response"}]
111    UnexpectedResponse,
112
113    /// DigestMismatch is the error when the digest is mismatch.
114    #[error{"digest mismatch expected: {0}, actual: {1}"}]
115    DigestMismatch(String, String),
116
117    /// ContentLengthMismatch is the error when the content length is mismatch.
118    #[error("content length mismatch expected: {0}, actual: {1}")]
119    ContentLengthMismatch(u64, u64),
120
121    /// MaxScheduleCountExceeded is the error when the max schedule count is exceeded.
122    #[error("max schedule count {0} exceeded")]
123    MaxScheduleCountExceeded(u32),
124
125    /// InvalidContentLength is the error when the content length is invalid.
126    #[error("invalid content length")]
127    InvalidContentLength,
128
129    /// InvalidPieceLength is the error when the piece length is invalid.
130    #[error("invalid piece length")]
131    InvalidPieceLength,
132
133    /// InvalidParameter is the error when the parameter is invalid.
134    #[error("invalid parameter")]
135    InvalidParameter,
136
137    /// Infallible is the error for infallible.
138    #[error(transparent)]
139    Infallible(#[from] std::convert::Infallible),
140
141    /// Utf8 is the error for utf8.
142    #[error(transparent)]
143    Utf8(#[from] std::str::Utf8Error),
144
145    /// Unknown is the error when the error is unknown.
146    #[error("unknown {0}")]
147    Unknown(String),
148
149    /// Unimplemented is the error when the feature is not implemented.
150    #[error{"unimplemented"}]
151    Unimplemented,
152
153    /// EmptyHTTPRangeError is the error when the range fallback error is empty.
154    #[error{"RangeUnsatisfiable: Failed to parse range fallback error, please file an issue"}]
155    EmptyHTTPRangeError,
156
157    /// Unauthorized is the error for unauthorized.
158    #[error{"unauthorized"}]
159    Unauthorized,
160
161    /// ArrayTryFromSliceError is the error for array try from slice.
162    #[error(transparent)]
163    ArrayTryFromSliceError(#[from] std::array::TryFromSliceError),
164
165    /// VortexProtocolStatus is the error for vortex protocol status.
166    #[error("vortex protocol status: code={0:?}, message={1}")]
167    VortexProtocolStatus(vortex_protocol::tlv::error::Code, String),
168
169    /// VortexProtocolError is the error for vortex protocol.
170    #[error(transparent)]
171    VortexProtocolError(#[from] vortex_protocol::error::Error),
172
173    /// TonicStatus is the error for tonic status.
174    #[error(transparent)]
175    TonicStatus(#[from] tonic::Status),
176
177    /// TonicTransportError is the error for tonic transport.
178    #[error(transparent)]
179    TonicTransportError(#[from] tonic::transport::Error),
180
181    /// TonicReflectionServerError is the error for tonic reflection server.
182    #[error(transparent)]
183    TonicReflectionServerError(#[from] tonic_reflection::server::Error),
184
185    /// TonicStreamElapsed is the error for tonic stream elapsed.
186    #[error(transparent)]
187    TokioStreamElapsed(#[from] tokio_stream::Elapsed),
188
189    // TokioTimeErrorElapsed is the error for tokio time elapsed.
190    #[error(transparent)]
191    TokioTimeErrorElapsed(#[from] tokio::time::error::Elapsed),
192
193    /// HeadersError is the error for headers.
194    #[error(transparent)]
195    HeadersError(#[from] headers::Error),
196
197    // InvalidHeaderName is the error for invalid header name.
198    #[error(transparent)]
199    HTTTHeaderInvalidHeaderName(#[from] http::header::InvalidHeaderName),
200
201    // InvalidHeaderValue is the error for invalid header value.
202    #[error(transparent)]
203    HTTTHeaderInvalidHeaderValue(#[from] http::header::InvalidHeaderValue),
204
205    /// URLParseError is the error for url parse.
206    #[error(transparent)]
207    URLParseError(#[from] url::ParseError),
208
209    /// ReqwestError is the error for reqwest.
210    #[error(transparent)]
211    ReqwestError(#[from] reqwest::Error),
212
213    /// ReqwestMiddlewareError is the error for reqwest middleware.
214    #[error(transparent)]
215    ReqwestMiddlewareError(#[from] reqwest_middleware::Error),
216
217    /// OpenDALError is the error for opendal.
218    #[error(transparent)]
219    OpenDALError(#[from] opendal::Error),
220
221    /// HyperError is the error for hyper.
222    #[error(transparent)]
223    HyperError(#[from] hyper::Error),
224
225    /// BackendError is the error for backend.
226    #[error(transparent)]
227    BackendError(Box<BackendError>),
228
229    /// HyperUtilClientLegacyError is the error for hyper util client legacy.
230    #[error(transparent)]
231    HyperUtilClientLegacyError(#[from] hyper_util::client::legacy::Error),
232
233    /// ExternalError is the error for external error.
234    #[error(transparent)]
235    ExternalError(#[from] ExternalError),
236
237    /// MaxDownloadFilesExceeded is the error for max download files exceeded.
238    #[error("max number of files to download exceeded: {0}")]
239    MaxDownloadFilesExceeded(usize),
240
241    /// Unsupported is the error for unsupported.
242    #[error("unsupported {0}")]
243    Unsupported(String),
244
245    /// TokioJoinError is the error for tokio join.
246    #[error(transparent)]
247    TokioJoinError(tokio::task::JoinError),
248
249    /// ValidationError is the error for validate.
250    #[error("validate failed: {0}")]
251    ValidationError(String),
252}
253
254/// SendError is the error for send.
255impl<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
261/// SendTimeoutError is the error for send timeout.
262impl<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}