hf_fetch_model/error.rs
1// SPDX-License-Identifier: MIT OR Apache-2.0
2
3//! Error types for hf-fetch-model.
4//!
5//! All fallible operations in this crate return [`FetchError`].
6//! [`FileFailure`] provides structured per-file error reporting.
7
8use std::path::PathBuf;
9
10/// Errors that can occur during model fetching.
11#[derive(Debug, thiserror::Error)]
12#[non_exhaustive]
13pub enum FetchError {
14 /// The hf-hub API returned an error.
15 #[error("hf-hub API error: {0}")]
16 Api(#[from] hf_hub::api::tokio::ApiError),
17
18 /// An I/O error occurred while accessing the local filesystem.
19 #[error("I/O error at {path}: {source}")]
20 Io {
21 /// The path that caused the error.
22 path: PathBuf,
23 /// The underlying I/O error.
24 source: std::io::Error,
25 },
26
27 /// The repository was not found or is inaccessible.
28 #[error("repository not found: {repo_id}")]
29 RepoNotFound {
30 /// The repository identifier that was not found.
31 repo_id: String,
32 },
33
34 /// Authentication failed (missing or invalid token).
35 #[error("authentication failed: {reason}")]
36 Auth {
37 /// Description of the authentication failure.
38 reason: String,
39 },
40
41 /// An invalid glob pattern was provided for filtering.
42 #[error("invalid glob pattern: {pattern}: {reason}")]
43 InvalidPattern {
44 /// The glob pattern that failed to parse.
45 pattern: String,
46 /// Description of the parse error.
47 reason: String,
48 },
49
50 /// SHA256 checksum mismatch after download.
51 #[error("checksum mismatch for {filename}: expected {expected}, got {actual}")]
52 Checksum {
53 /// The filename that failed verification.
54 filename: String,
55 /// The expected SHA256 hex digest.
56 expected: String,
57 /// The actual SHA256 hex digest computed from the file.
58 actual: String,
59 },
60
61 /// A download operation timed out.
62 #[error("timeout downloading {filename} after {seconds}s")]
63 Timeout {
64 /// The filename that timed out.
65 filename: String,
66 /// The timeout duration in seconds.
67 seconds: u64,
68 },
69
70 /// One or more files failed to download.
71 ///
72 /// Contains the successful path and a list of per-file failures.
73 #[error("{} file(s) failed to download", failures.len())]
74 PartialDownload {
75 /// The snapshot directory (if any files succeeded).
76 path: Option<PathBuf>,
77 /// Per-file failure details.
78 failures: Vec<FileFailure>,
79 },
80
81 /// A chunked (multi-connection) download failed.
82 #[error("chunked download failed for {filename}: {reason}")]
83 ChunkedDownload {
84 /// The filename that failed.
85 filename: String,
86 /// Description of the failure.
87 reason: String,
88 },
89
90 /// An HTTP request to the `HuggingFace` API failed.
91 #[error("HTTP error: {0}")]
92 Http(String),
93
94 /// An invalid argument was provided.
95 #[error("{0}")]
96 InvalidArgument(String),
97}
98
99/// A per-file download failure with structured context.
100#[derive(Debug, Clone)]
101pub struct FileFailure {
102 /// The filename that failed.
103 pub filename: String,
104 /// Human-readable description of the failure.
105 pub reason: String,
106 /// Whether this failure is likely to succeed on retry.
107 pub retryable: bool,
108}
109
110impl std::fmt::Display for FileFailure {
111 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
112 write!(
113 f,
114 "{}: {} (retryable: {})",
115 self.filename, self.reason, self.retryable
116 )
117 }
118}