1use std::fmt;
2
3pub type BoxError = Box<dyn std::error::Error + Send + Sync>;
5
6pub type Result<T> = std::result::Result<T, BoxError>;
8
9#[derive(Debug, Default, Copy, Clone)]
11pub struct BadVersion;
12
13impl fmt::Display for BadVersion {
14 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
15 f.pad("Unknown HTTP version")
16 }
17}
18
19impl std::error::Error for BadVersion {}
20
21#[derive(Debug, Default, Copy, Clone)]
23pub struct BadHeader;
24
25impl fmt::Display for BadHeader {
26 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27 f.pad("Error parsing header value")
28 }
29}
30
31impl std::error::Error for BadHeader {}
32
33#[derive(Debug, Default, Copy, Clone)]
35pub struct BadRequest;
36
37impl fmt::Display for BadRequest {
38 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39 f.pad("Request object is not cloneable. Are you passing a streaming body?")
40 }
41}
42
43impl std::error::Error for BadRequest {}
44
45#[derive(Debug)]
68pub enum HttpCacheError {
69 Client(BoxError),
71 Cache(String),
73 BadRequest(BadRequest),
75 Http(BoxError),
77 Body(BoxError),
79 Streaming(StreamingError),
81 Other(BoxError),
83}
84
85impl HttpCacheError {
86 pub fn cache<S: Into<String>>(message: S) -> Self {
96 Self::Cache(message.into())
97 }
98
99 pub fn http<E: Into<BoxError>>(error: E) -> Self {
109 Self::Http(error.into())
110 }
111
112 pub fn body<E: Into<BoxError>>(error: E) -> Self {
122 Self::Body(error.into())
123 }
124
125 pub fn client<E: Into<BoxError>>(error: E) -> Self {
135 Self::Client(error.into())
136 }
137
138 pub fn other<E: Into<BoxError>>(error: E) -> Self {
148 Self::Other(error.into())
149 }
150
151 pub fn is_cache_error(&self) -> bool {
153 matches!(self, Self::Cache(_))
154 }
155
156 pub fn is_client_error(&self) -> bool {
158 matches!(self, Self::Client(_))
159 }
160
161 pub fn is_streaming_error(&self) -> bool {
163 matches!(self, Self::Streaming(_))
164 }
165
166 pub fn is_bad_request(&self) -> bool {
168 matches!(self, Self::BadRequest(_))
169 }
170}
171
172impl fmt::Display for HttpCacheError {
173 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
174 match self {
175 Self::Client(e) => write!(f, "HTTP client error: {e}"),
176 Self::Cache(msg) => write!(f, "Cache error: {msg}"),
177 Self::BadRequest(e) => write!(f, "Request error: {e}"),
178 Self::Http(e) => write!(f, "HTTP error: {e}"),
179 Self::Body(e) => write!(f, "Body processing error: {e}"),
180 Self::Streaming(e) => write!(f, "Streaming error: {e}"),
181 Self::Other(e) => write!(f, "Other error: {e}"),
182 }
183 }
184}
185
186impl std::error::Error for HttpCacheError {
187 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
188 match self {
189 Self::Client(e) => Some(e.as_ref()),
190 Self::Cache(_) => None,
191 Self::BadRequest(e) => Some(e),
192 Self::Http(e) => Some(e.as_ref()),
193 Self::Body(e) => Some(e.as_ref()),
194 Self::Streaming(e) => Some(e),
195 Self::Other(e) => Some(e.as_ref()),
196 }
197 }
198}
199
200impl From<BadRequest> for HttpCacheError {
203 fn from(error: BadRequest) -> Self {
204 Self::BadRequest(error)
205 }
206}
207
208impl From<BadHeader> for HttpCacheError {
209 fn from(error: BadHeader) -> Self {
210 Self::Http(Box::new(error))
211 }
212}
213
214impl From<BadVersion> for HttpCacheError {
215 fn from(error: BadVersion) -> Self {
216 Self::Http(Box::new(error))
217 }
218}
219
220impl From<StreamingError> for HttpCacheError {
221 fn from(error: StreamingError) -> Self {
222 Self::Streaming(error)
223 }
224}
225
226impl From<BoxError> for HttpCacheError {
227 fn from(error: BoxError) -> Self {
228 Self::Other(error)
229 }
230}
231
232impl From<std::io::Error> for HttpCacheError {
233 fn from(error: std::io::Error) -> Self {
234 Self::Other(Box::new(error))
235 }
236}
237
238impl From<http::Error> for HttpCacheError {
239 fn from(error: http::Error) -> Self {
240 Self::Http(Box::new(error))
241 }
242}
243
244impl From<http::header::InvalidHeaderValue> for HttpCacheError {
245 fn from(error: http::header::InvalidHeaderValue) -> Self {
246 Self::Http(Box::new(error))
247 }
248}
249
250impl From<http::header::InvalidHeaderName> for HttpCacheError {
251 fn from(error: http::header::InvalidHeaderName) -> Self {
252 Self::Http(Box::new(error))
253 }
254}
255
256impl From<http::uri::InvalidUri> for HttpCacheError {
257 fn from(error: http::uri::InvalidUri) -> Self {
258 Self::Http(Box::new(error))
259 }
260}
261
262impl From<http::method::InvalidMethod> for HttpCacheError {
263 fn from(error: http::method::InvalidMethod) -> Self {
264 Self::Http(Box::new(error))
265 }
266}
267
268impl From<http::status::InvalidStatusCode> for HttpCacheError {
269 fn from(error: http::status::InvalidStatusCode) -> Self {
270 Self::Http(Box::new(error))
271 }
272}
273
274#[cfg(feature = "url-standard")]
275impl From<url::ParseError> for HttpCacheError {
276 fn from(error: url::ParseError) -> Self {
277 Self::Http(Box::new(error))
278 }
279}
280
281pub type HttpCacheResult<T> = std::result::Result<T, HttpCacheError>;
288
289#[derive(Debug)]
291pub struct StreamingError {
292 inner: BoxError,
293 kind: StreamingErrorKind,
294}
295
296#[derive(Debug, Clone, Copy)]
298pub enum StreamingErrorKind {
299 Io,
301 Serialization,
303 Concurrency,
305 Consistency,
307 TempFile,
309 ContentAddressing,
311 Client,
313 Other,
315}
316
317impl StreamingError {
318 pub fn new<E: Into<BoxError>>(error: E) -> Self {
320 Self { inner: error.into(), kind: StreamingErrorKind::Other }
321 }
322
323 pub fn with_kind<E: Into<BoxError>>(
325 error: E,
326 kind: StreamingErrorKind,
327 ) -> Self {
328 Self { inner: error.into(), kind }
329 }
330
331 pub fn io<E: Into<BoxError>>(error: E) -> Self {
333 Self::with_kind(error, StreamingErrorKind::Io)
334 }
335
336 pub fn serialization<E: Into<BoxError>>(error: E) -> Self {
338 Self::with_kind(error, StreamingErrorKind::Serialization)
339 }
340
341 pub fn concurrency<E: Into<BoxError>>(error: E) -> Self {
343 Self::with_kind(error, StreamingErrorKind::Concurrency)
344 }
345
346 pub fn consistency<E: Into<BoxError>>(error: E) -> Self {
348 Self::with_kind(error, StreamingErrorKind::Consistency)
349 }
350
351 pub fn temp_file<E: Into<BoxError>>(error: E) -> Self {
353 Self::with_kind(error, StreamingErrorKind::TempFile)
354 }
355
356 pub fn content_addressing<E: Into<BoxError>>(error: E) -> Self {
358 Self::with_kind(error, StreamingErrorKind::ContentAddressing)
359 }
360
361 pub fn client<E: Into<BoxError>>(error: E) -> Self {
363 Self::with_kind(error, StreamingErrorKind::Client)
364 }
365
366 pub fn kind(&self) -> &StreamingErrorKind {
368 &self.kind
369 }
370}
371
372impl fmt::Display for StreamingError {
373 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
374 write!(f, "Streaming error: {}", self.inner)
375 }
376}
377
378impl std::error::Error for StreamingError {
379 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
380 Some(&*self.inner)
381 }
382}
383
384impl From<BoxError> for StreamingError {
385 fn from(error: BoxError) -> Self {
386 Self::new(error)
387 }
388}
389
390impl From<std::convert::Infallible> for StreamingError {
391 fn from(never: std::convert::Infallible) -> Self {
392 match never {}
393 }
394}
395
396impl From<std::io::Error> for StreamingError {
397 fn from(error: std::io::Error) -> Self {
398 Self::new(error)
399 }
400}
401
402impl From<HttpCacheError> for StreamingError {
403 fn from(error: HttpCacheError) -> Self {
404 match error {
405 HttpCacheError::Streaming(streaming_err) => streaming_err,
406 _ => Self::new(Box::new(error)),
407 }
408 }
409}
410
411#[derive(Debug)]
426pub enum ClientStreamingError {
427 Client {
429 client: String,
431 error: BoxError,
433 },
434 HttpCache(StreamingError),
436 Other(BoxError),
438}
439
440impl ClientStreamingError {
441 pub fn client<C, E>(client: C, error: E) -> Self
451 where
452 C: Into<String>,
453 E: Into<BoxError>,
454 {
455 Self::Client { client: client.into(), error: error.into() }
456 }
457
458 pub fn http_cache(error: StreamingError) -> Self {
469 Self::HttpCache(error)
470 }
471
472 pub fn other<E: Into<BoxError>>(error: E) -> Self {
482 Self::Other(error.into())
483 }
484}
485
486impl fmt::Display for ClientStreamingError {
487 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
488 match self {
489 Self::Client { client, error } => {
490 write!(f, "{} streaming error: {}", client, error)
491 }
492 Self::HttpCache(e) => {
493 write!(f, "HTTP cache streaming error: {}", e)
494 }
495 Self::Other(e) => write!(f, "Streaming error: {}", e),
496 }
497 }
498}
499
500impl std::error::Error for ClientStreamingError {
501 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
502 match self {
503 Self::Client { error, .. } => Some(error.as_ref()),
504 Self::HttpCache(e) => Some(e),
505 Self::Other(e) => Some(e.as_ref()),
506 }
507 }
508}
509
510impl From<StreamingError> for ClientStreamingError {
511 fn from(error: StreamingError) -> Self {
512 Self::HttpCache(error)
513 }
514}
515
516impl From<BoxError> for ClientStreamingError {
517 fn from(error: BoxError) -> Self {
518 Self::Other(error)
519 }
520}
521
522impl From<ClientStreamingError> for HttpCacheError {
523 fn from(error: ClientStreamingError) -> Self {
524 match error {
525 ClientStreamingError::HttpCache(streaming_err) => {
526 Self::Streaming(streaming_err)
527 }
528 ClientStreamingError::Client { error, .. } => Self::Client(error),
529 ClientStreamingError::Other(error) => Self::Other(error),
530 }
531 }
532}
533
534impl From<ClientStreamingError> for StreamingError {
535 fn from(error: ClientStreamingError) -> Self {
536 match error {
537 ClientStreamingError::HttpCache(streaming_err) => streaming_err,
538 ClientStreamingError::Client { client, error } => {
539 let client_error =
541 format!("Client '{}' error: {}", client, error);
542 Self::client(client_error)
543 }
544 ClientStreamingError::Other(error) => Self::new(error),
545 }
546 }
547}