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("Invalid configuration: {0}")]
28 InvalidConfig(String),
29
30 #[error("Sandbox already running")]
31 AlreadyRunning,
32
33 #[error("Sandbox not running")]
34 NotRunning,
35
36 #[error("Timeout exceeded")]
37 Timeout,
38
39 #[error("Process exited with code {code}")]
40 ProcessExit { code: i32 },
41
42 #[error("Process killed by signal {signal}")]
43 ProcessSignal { signal: i32 },
44
45 #[error("Permission denied: {0}")]
46 PermissionDenied(String),
47
48 #[error("Resource exhausted: {0}")]
49 ResourceExhausted(String),
50
51 #[error("Process monitoring error: {0}")]
52 ProcessMonitoring(String),
53
54 #[error("Unknown error: {0}")]
55 Unknown(String),
56}
57
58#[cfg(test)]
59mod tests {
60 use super::*;
61
62 #[test]
63 fn test_error_display() {
64 let err = SandboxError::Timeout;
65 assert_eq!(err.to_string(), "Timeout exceeded");
66 }
67
68 #[test]
69 fn test_error_from_io() {
70 let io_err = io::Error::new(io::ErrorKind::NotFound, "file not found");
71 let sandbox_err = SandboxError::from(io_err);
72 assert!(sandbox_err.to_string().contains("IO error"));
73 }
74
75 #[test]
76 fn test_result_type() {
77 fn returns_result() -> Result<i32> {
78 Ok(42)
79 }
80 assert_eq!(returns_result().unwrap(), 42);
81 }
82
83 #[test]
84 fn test_result_error() {
85 fn returns_error() -> Result<i32> {
86 Err(SandboxError::Timeout)
87 }
88 assert!(returns_error().is_err());
89 }
90}