oro_script/
error.rs

1use miette::Diagnostic;
2use thiserror::Error;
3
4#[derive(Debug, Error, Diagnostic)]
5pub enum OroScriptError {
6    /// Generic IO-related error. Refer to the error message for more details.
7    #[error("{0}")]
8    #[diagnostic(code(oro_script::io_error), url(docsrs))]
9    IoError(String, #[source] std::io::Error),
10
11    /// Generic serde-related error. Refer to the error message for more
12    /// details.
13    #[error(transparent)]
14    #[diagnostic(code(oro_script::serde_error), url(docsrs))]
15    SerdeError(#[from] serde_json::Error),
16
17    /// Failed to spawn child process when executing a script. Refer to the
18    /// error message for more details.
19    #[error("Failed to spawn child process.")]
20    #[diagnostic(code(oro_script::spawn_error), url(docsrs))]
21    SpawnError(#[source] std::io::Error),
22
23    /// Failed to find an event in a package's `package.json`. This means, for
24    /// example, that a `"postinstall"` script was requested, but not actually
25    /// present.
26    #[error("Failed to find event `{0}` in package.")]
27    #[diagnostic(code(oro_script::missing_event), url(docsrs))]
28    MissingEvent(String),
29
30    /// Failed to join new contents of PATH variable while trying to add a
31    /// `node_modules/.bin` entry to the PATH.
32    ///
33    /// When executing a script, the current package and their ancestors get
34    /// their `node_modules/.bin` directories added to the PATH. This error
35    /// means something went wrong while putting the variable back together.
36    /// For more details on what may have happened, refer to the error
37    /// message.
38    #[error("Failed to join new contents of PATH variable while trying to add a `node_modules/.bin` entry to the PATH.")]
39    #[diagnostic(code(oro_script::join_path_error), url(docsrs))]
40    JoinPathError(#[from] std::env::JoinPathsError),
41
42    /// Something went wrong while performing an operation on a script's
43    /// process. For more details, refer to the error message.
44    #[error("Error performing process operation on script.")]
45    #[diagnostic(code(oro_script::script_process_error), url(docsrs))]
46    ScriptProcessError(#[source] std::io::Error),
47
48    /// The script terminated with a non-zero exit code, meaning some error
49    /// happened with the script itself. Details may have been logged in the
50    /// log file/stdout/stderr.
51    #[error("Script exited with code {}", .0.code().unwrap_or(-1))]
52    #[diagnostic(code(oro_script::script_error), url(docsrs))]
53    ScriptError(std::process::ExitStatus, Option<Vec<u8>>, Option<Vec<u8>>),
54}
55
56pub(crate) type Result<T> = std::result::Result<T, OroScriptError>;
57
58pub trait IoContext {
59    type T;
60
61    fn io_context(self, context: impl FnOnce() -> String) -> Result<Self::T>;
62}
63
64impl<T> IoContext for std::result::Result<T, std::io::Error> {
65    type T = T;
66
67    fn io_context(self, context: impl FnOnce() -> String) -> Result<Self::T> {
68        self.map_err(|e| OroScriptError::IoError(context(), e))
69    }
70}