1use std::io;
4use thiserror::Error;
5
6pub type Result<T> = std::result::Result<T, SandboxError>;
8
9#[derive(Error, Debug)]
11pub enum SandboxError {
12 #[error("IO error: {0}")]
13 Io(#[from] io::Error),
14
15 #[error("Syscall error: {0}")]
16 Syscall(String),
17
18 #[error("Cgroup error: {0}")]
19 Cgroup(String),
20
21 #[error("Namespace error: {0}")]
22 Namespace(String),
23
24 #[error("Seccomp error: {0}")]
25 Seccomp(String),
26
27 #[error("Landlock error: {0}")]
28 Landlock(String),
29
30 #[error("Invalid configuration: {0}")]
31 InvalidConfig(String),
32
33 #[error("Sandbox already running")]
34 AlreadyRunning,
35
36 #[error("Sandbox not running")]
37 NotRunning,
38
39 #[error("Timeout exceeded")]
40 Timeout,
41
42 #[error("Process exited with code {code}")]
43 ProcessExit { code: i32 },
44
45 #[error("Process killed by signal {signal}")]
46 ProcessSignal { signal: i32 },
47
48 #[error("Permission denied: {0}")]
49 PermissionDenied(String),
50
51 #[error("Resource exhausted: {0}")]
52 ResourceExhausted(String),
53
54 #[error("Process monitoring error: {0}")]
55 ProcessMonitoring(String),
56
57 #[error("Feature not available: {0}")]
58 FeatureNotAvailable(String),
59
60 #[error("Unknown error: {0}")]
61 Unknown(String),
62}
63
64#[cfg(test)]
65mod tests {
66 use super::*;
67
68 #[test]
69 fn test_error_display() {
70 let err = SandboxError::Timeout;
71 assert_eq!(err.to_string(), "Timeout exceeded");
72 }
73
74 #[test]
75 fn test_error_from_io() {
76 let io_err = io::Error::new(io::ErrorKind::NotFound, "file not found");
77 let sandbox_err = SandboxError::from(io_err);
78 assert!(sandbox_err.to_string().contains("IO error"));
79 }
80
81 #[test]
82 fn test_result_type() {
83 fn returns_result() -> Result<i32> {
84 Ok(42)
85 }
86 assert_eq!(returns_result().unwrap(), 42);
87 }
88
89 #[test]
90 fn test_result_error() {
91 fn returns_error() -> Result<i32> {
92 Err(SandboxError::Timeout)
93 }
94 assert!(returns_error().is_err());
95 }
96
97 #[test]
98 fn test_feature_not_available() {
99 let err = SandboxError::FeatureNotAvailable("landlock".to_string());
100 assert!(err.to_string().contains("landlock"));
101 }
102
103 #[test]
104 fn test_landlock_error() {
105 let err = SandboxError::Landlock("ruleset failed".to_string());
106 assert!(err.to_string().contains("Landlock"));
107 }
108}