1use std::path::PathBuf;
2
3use thiserror::Error as ThisError;
4
5pub const SANDBOX_MISCONFIGURATION_EXIT_CODE: i32 = 2;
7
8#[derive(Debug, ThisError)]
10pub enum Error {
11 #[error("missing command")]
13 MissingCommand,
14 #[error("invalid cwd: {0}")]
16 InvalidCwd(PathBuf),
17 #[error("sandbox hardening failed: {0}")]
19 Hardening(#[source] std::io::Error),
20 #[error("failed to spawn child command: {0}")]
22 Spawn(#[source] std::io::Error),
23 #[error("failed to wait for child command: {0}")]
25 Wait(#[source] std::io::Error),
26 #[error(transparent)]
28 SandboxPolicy(#[from] heimdall_sandbox_policy::Error),
29 #[cfg(target_os = "linux")]
31 #[error(transparent)]
32 LinuxSandbox(#[from] heimdall_linux_sandbox::Error),
33 #[cfg(target_os = "macos")]
35 #[error(transparent)]
36 MacosSandbox(#[from] heimdall_macos_sandbox::Error),
37 #[error("sandbox misconfiguration: {0}")]
39 SandboxMisconfiguration(String),
40}
41
42impl Error {
43 #[must_use]
45 pub const fn missing_command() -> Self {
46 Self::MissingCommand
47 }
48
49 #[must_use]
51 pub fn invalid_cwd(cwd: PathBuf) -> Self {
52 Self::InvalidCwd(cwd)
53 }
54
55 #[must_use]
57 pub fn hardening(error: std::io::Error) -> Self {
58 Self::Hardening(error)
59 }
60
61 #[must_use]
63 pub fn spawn(error: std::io::Error) -> Self {
64 Self::Spawn(error)
65 }
66
67 #[must_use]
69 pub fn sandbox_misconfiguration(message: impl Into<String>) -> Self {
70 Self::SandboxMisconfiguration(message.into())
71 }
72
73 #[must_use]
77 pub const fn exit_code(&self) -> i32 {
78 match self {
79 Self::MissingCommand
80 | Self::InvalidCwd(_)
81 | Self::Hardening(_)
82 | Self::Spawn(_)
83 | Self::Wait(_)
84 | Self::SandboxPolicy(_)
85 | Self::SandboxMisconfiguration(_) => SANDBOX_MISCONFIGURATION_EXIT_CODE,
86 #[cfg(target_os = "linux")]
87 Self::LinuxSandbox(_) => SANDBOX_MISCONFIGURATION_EXIT_CODE,
88 #[cfg(target_os = "macos")]
89 Self::MacosSandbox(_) => SANDBOX_MISCONFIGURATION_EXIT_CODE,
90 }
91 }
92}
93
94#[cfg(test)]
95mod tests {
96 use std::io;
97
98 use super::*;
99
100 #[test]
101 fn runtime_errors_map_to_documented_exit_codes() {
102 assert_eq!(
103 Error::missing_command().exit_code(),
104 SANDBOX_MISCONFIGURATION_EXIT_CODE
105 );
106 assert_eq!(
107 Error::invalid_cwd(PathBuf::from("missing")).exit_code(),
108 SANDBOX_MISCONFIGURATION_EXIT_CODE
109 );
110 assert_eq!(
111 Error::hardening(io::Error::other("failed")).exit_code(),
112 SANDBOX_MISCONFIGURATION_EXIT_CODE
113 );
114 assert_eq!(
115 Error::spawn(io::Error::other("failed")).exit_code(),
116 SANDBOX_MISCONFIGURATION_EXIT_CODE
117 );
118 }
119}