snix_build_glue/fetchers/
error.rs1use nix_compat::nixhash::NixHash;
2use nix_compat::store_path;
3use snix_castore::import;
4use url::Url;
5
6#[derive(Debug, thiserror::Error)]
7pub enum FetcherError {
8 #[error("hash mismatch in file downloaded from {}:\n wanted: {}\n got: {}", _0.0, _0.1, _0.2)]
9 HashMismatch(Box<(Url, NixHash, NixHash)>),
10
11 #[error("Invalid hash type '{0}' for fetcher")]
12 InvalidHashType(&'static str),
13
14 #[error("Unable to parse URL: {0}")]
15 InvalidUrl(#[from] url::ParseError),
16
17 #[error(transparent)]
18 Http(#[from] reqwest::Error),
19
20 #[error(transparent)]
21 Io(#[from] std::io::Error),
22
23 #[error(transparent)]
24 Import(Box<snix_castore::import::IngestionError<import::archive::Error>>),
25
26 #[error("Error calculating store path for fetcher output: {0}")]
27 StorePath(#[from] store_path::ParseStorePathError),
28}
29
30impl FetcherError {
31 pub fn hash_mismatch(url: Url, expected: NixHash, actual: NixHash) -> Self {
33 Self::HashMismatch(Box::new((url, expected, actual)))
34 }
35}
36
37impl From<snix_castore::import::IngestionError<import::archive::Error>> for FetcherError {
39 fn from(value: snix_castore::import::IngestionError<import::archive::Error>) -> Self {
40 Self::Import(Box::new(value))
41 }
42}
43
44#[cfg(test)]
45mod tests {
46 use super::*;
47
48 #[test]
49 fn test_hash_mismatch_display() {
50 let err = FetcherError::hash_mismatch(
51 Url::parse("https://example.com/foo.tar.gz").unwrap(),
52 NixHash::Sha256([0; 32]),
53 NixHash::Sha256([1; 32]),
54 );
55 let msg = err.to_string();
56 assert!(msg.contains("https://example.com/foo.tar.gz"));
57 assert!(
58 msg.contains(
59 "wanted: sha256:0000000000000000000000000000000000000000000000000000000000000000"
60 ) || msg.contains("wanted:")
61 );
62 assert!(!msg.contains("wanted: 0.1"));
63 }
64}