Skip to main content

http_ferry/
error.rs

1use std::io;
2use std::path::PathBuf;
3
4use reqwest::StatusCode;
5
6/// Errors produced by the transfer engine.
7///
8/// [`Source`](Error::Source) is the seam for caller-supplied failures: the URL
9/// resolver and the input item stream hand their own error types to the engine
10/// boxed through this variant, so the engine never needs to know about a
11/// consumer's domain errors.
12#[derive(Debug, thiserror::Error)]
13pub enum Error {
14    #[error("{algorithm} mismatch for {url}: expected {expected}, got {actual}")]
15    ChecksumMismatch {
16        algorithm: &'static str,
17        url: String,
18        expected: String,
19        actual: String,
20    },
21    #[error("download path is not a single safe file name: {}", .path.display())]
22    InvalidDownloadPath { path: PathBuf },
23    #[error("invalid range response for {url}: {details}")]
24    InvalidRangeResponse { url: String, details: String },
25    #[error("I/O failed: {0}")]
26    Io(#[from] io::Error),
27    #[error("resource not found: {0}")]
28    NotFound(String),
29    #[error("HTTP request failed: {0}")]
30    Request(#[from] reqwest::Error),
31    #[cfg(feature = "s3")]
32    #[error("S3 operation failed: {0}")]
33    S3(Box<dyn std::error::Error + Send + Sync>),
34    #[error("downloaded {actual} bytes from {url}; expected {expected}")]
35    SizeMismatch {
36        url: String,
37        expected: u64,
38        actual: u64,
39    },
40    #[error("source resolution failed: {0}")]
41    Source(Box<dyn std::error::Error + Send + Sync>),
42    #[error("unexpected status: {0}")]
43    Status(StatusCode),
44    #[error("invalid URL: {0}")]
45    Url(#[from] url::ParseError),
46}
47
48impl Error {
49    /// Wrap a caller-supplied error — from the URL resolver or the input item
50    /// stream — as a [`Source`](Error::Source). Shorthand for
51    /// `Error::Source(Box::new(err))`; accepts anything boxable, including a
52    /// `&str`/`String` message.
53    pub fn from_source(err: impl Into<Box<dyn std::error::Error + Send + Sync>>) -> Self {
54        Error::Source(err.into())
55    }
56}