dev_scripts/
error.rs

1//! Error handling for the `dev-scripts` executable.
2
3use std::path::PathBuf;
4
5use colored::Colorize;
6use log::SetLoggerError;
7
8/// The error that can occur when using the `dev-scripts` executable.
9#[derive(Debug, thiserror::Error)]
10pub enum Error {
11    /// An `alpm_buildinfo::Error` occurred.
12    #[error(transparent)]
13    AlpmBuildinfo(#[from] alpm_buildinfo::Error),
14
15    /// An `alpm_pkginfo::Error` occurred.
16    #[error(transparent)]
17    AlpmPackageInfo(#[from] alpm_pkginfo::Error),
18
19    /// An `alpm_mtree::Error` occurred.
20    #[error(transparent)]
21    AlpmMtree(#[from] alpm_mtree::Error),
22
23    /// An `alpm_srcinfo::Error` occurred.
24    #[error(transparent)]
25    AlpmSourceInfo(#[from] alpm_srcinfo::Error),
26
27    /// An `alpm_types::Error` occurred.
28    #[error(transparent)]
29    AlpmTypes(#[from] alpm_types::Error),
30
31    /// The logger cannot be setup.
32    #[error("Failed to setup the logger:\n{0}")]
33    SetupLogger(#[from] SetLoggerError),
34
35    /// It is not possible to get the cache directory for the current user.
36    #[error("Failed to determine the current user's cache directory")]
37    CannotGetCacheDir,
38
39    /// A command failed.
40    #[error("A command failed:{message}\nstdout:\n{stdout}\nstderr:\n{stderr}")]
41    CommandFailed {
42        /// A message explaining what command failed.
43        message: String,
44        /// The stdout of the failed command.
45        stdout: String,
46        /// The stderr of the failed command.
47        stderr: String,
48    },
49
50    #[error("An HTTP query failed while {context}:\n{source}")]
51    HttpQueryFailed {
52        /// The context in which the error occurred.
53        ///
54        /// This is meant to complete the sentence "An HTTP query failed while {context}".
55        context: String,
56        /// The source error.
57        source: reqwest::Error,
58    },
59
60    /// An I/O error occurred.
61    #[error("I/O error while {context}:\n{source}")]
62    Io {
63        /// The context in which the error occurred.
64        ///
65        /// This is meant to complete the sentence "I/O error while ".
66        context: String,
67        /// The source error.
68        source: std::io::Error,
69    },
70
71    /// An I/O error occurred at a path.
72    #[error("I/O error at path {path} while {context}:\n{source}")]
73    IoPath {
74        /// The path at which the error occurred.
75        path: PathBuf,
76        /// The context in which the error occurred.
77        ///
78        /// This is meant to complete the sentence "I/O error at path while ".
79        context: String,
80        /// The source error.
81        source: std::io::Error,
82    },
83
84    /// A JSON error occurred.
85    #[error("JSON error while {context}:\n{source}")]
86    Json {
87        /// The context in which the error occurred.
88        ///
89        /// This is meant to complete the sentence "JSON error while ".
90        context: String,
91        /// The source error.
92        source: serde_json::Error,
93    },
94
95    /// A winnow parser for a type didn't work and produced an error.
96    #[error("Parser error:\n{0}")]
97    Parser(String),
98
99    #[error("Rsync report error:\n{message}")]
100    RsyncReport { message: String },
101
102    /// A test run failed.
103    #[error(
104        "The test run failed\n{}",
105        failures
106            .iter()
107            .map(|(index, path, message)| {
108                let index = format!("[{index}]").bold().red();
109                format!("{index} {} failed with error:\n{message}", path.to_string_lossy().bold())})
110            .collect::<Vec<_>>()
111            .join("\n")
112    )]
113    TestFailed {
114        /// The failed items as tuples of index, paths and messages.
115        failures: Vec<(usize, PathBuf, String)>,
116    },
117
118    /// A `voa::Error` occurred.
119    #[error(transparent)]
120    Voa(#[from] voa::Error),
121
122    #[error("Verifying the file {file:?} with signature {signature:?} failed:\n{context}")]
123    VoaVerificationFailed {
124        /// The path of the data file that failed verification.
125        file: PathBuf,
126        /// The path of the signature file that failed verification.
127        signature: PathBuf,
128        /// Additional context.
129        context: String,
130    },
131}
132
133impl<'a> From<winnow::error::ParseError<&'a str, winnow::error::ContextError>>
134    for crate::error::Error
135{
136    /// Converts a [`winnow::error::ParseError`] into an [`Error::Parser`].
137    fn from(value: winnow::error::ParseError<&'a str, winnow::error::ContextError>) -> Self {
138        Self::Parser(value.to_string())
139    }
140}