Skip to main content

nucleus/
error.rs

1use std::path::PathBuf;
2
3#[derive(Debug, thiserror::Error)]
4pub enum NucleusError {
5    #[error("Failed to create namespace: {0}")]
6    NamespaceError(String),
7
8    #[error("Failed to configure cgroup: {0}")]
9    CgroupError(String),
10
11    #[error("Failed to mount filesystem: {0}")]
12    FilesystemError(String),
13
14    #[error("Failed to pivot root: {0}")]
15    PivotRootError(String),
16
17    #[error("Failed to populate context: {0}")]
18    ContextError(String),
19
20    #[error("Failed to drop capabilities: {0}")]
21    CapabilityError(String),
22
23    #[error("Failed to apply seccomp filter: {0}")]
24    SeccompError(String),
25
26    #[error("Failed to apply Landlock policy: {0}")]
27    LandlockError(String),
28
29    #[error("Invalid resource limit: {0}")]
30    InvalidResourceLimit(String),
31
32    #[error("Resource error: {0}")]
33    ResourceError(String),
34
35    #[error("Configuration error: {0}")]
36    ConfigError(String),
37
38    #[error("Invalid path: {path:?}")]
39    InvalidPath { path: PathBuf },
40
41    #[error("Process execution failed: {0}")]
42    ExecError(String),
43
44    #[error("gVisor runtime error: {0}")]
45    GVisorError(String),
46
47    #[error("Container not found: {0}")]
48    ContainerNotFound(String),
49
50    #[error("Ambiguous container reference: {0}")]
51    AmbiguousContainer(String),
52
53    #[error("Checkpoint error: {0}")]
54    CheckpointError(String),
55
56    #[error("Network error: {0}")]
57    NetworkError(String),
58
59    #[error("Attach error: {0}")]
60    AttachError(String),
61
62    #[error("Permission denied: {0}")]
63    PermissionDenied(String),
64
65    #[error("Container not running: {0}")]
66    ContainerNotRunning(String),
67
68    #[error("Syscall error: {0}")]
69    SyscallError(#[from] nix::Error),
70
71    #[error("IO error: {0}")]
72    IoError(#[from] std::io::Error),
73
74    #[error("Invalid state transition: from {from} to {to}")]
75    InvalidStateTransition { from: String, to: String },
76
77    #[error("OCI hook failed: {0}")]
78    HookError(String),
79
80    #[error("JSON serialization error: {0}")]
81    SerdeJsonError(#[from] serde_json::Error),
82}
83
84pub type Result<T> = std::result::Result<T, NucleusError>;
85
86/// Common trait for all state machine enums.
87///
88/// Each subsystem (filesystem, security, resources, isolation, network, checkpoint)
89/// defines its own state enum with domain-specific transition rules. This trait
90/// provides the shared `transition()` method so each enum only needs to implement
91/// `can_transition_to()`.
92pub trait StateTransition: std::fmt::Debug + Sized {
93    /// Return `true` if moving from `self` to `next` is a valid transition.
94    fn can_transition_to(&self, next: &Self) -> bool;
95
96    /// Return `true` if this state is terminal (no forward transitions).
97    fn is_terminal(&self) -> bool;
98
99    /// Attempt to transition, returning `Err(InvalidStateTransition)` on failure.
100    fn transition(self, next: Self) -> Result<Self> {
101        if self.can_transition_to(&next) {
102            Ok(next)
103        } else {
104            Err(NucleusError::InvalidStateTransition {
105                from: format!("{:?}", self),
106                to: format!("{:?}", next),
107            })
108        }
109    }
110}