Skip to main content

dev_scripts/
error.rs

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