Skip to main content

substrate_core/
error.rs

1//! The single error type crossing every port boundary.
2
3use thiserror::Error;
4
5/// Errors that may cross a substrate port boundary.
6///
7/// Adapters map their concrete failure modes (IO, process spawn, parse,
8/// network) onto these variants so that the core/application layers never
9/// depend on adapter-specific error types.
10#[derive(Debug, Error)]
11pub enum SubstrateError {
12    /// A requested entity (task, conversation, session) was not found.
13    #[error("not found: {0}")]
14    NotFound(String),
15
16    /// A lifecycle transition was rejected by the FSM.
17    #[error("invalid state transition: {from:?} -> {to:?}")]
18    InvalidTransition {
19        /// State we attempted to move away from.
20        from: crate::domain::TaskState,
21        /// State we attempted to move to.
22        to: crate::domain::TaskState,
23    },
24
25    /// An atomic claim/lease could not be acquired (already held).
26    #[error("claim conflict: {0}")]
27    ClaimConflict(String),
28
29    /// A backing engine (CLI/process) failed.
30    #[error("engine error: {0}")]
31    Engine(String),
32
33    /// A transport (mailbox/bus) operation failed.
34    #[error("transport error: {0}")]
35    Transport(String),
36
37    /// A store (persistence) operation failed.
38    #[error("store error: {0}")]
39    Store(String),
40
41    /// Routing could not select a target.
42    #[error("routing error: {0}")]
43    Routing(String),
44
45    /// Serialization / deserialization failed.
46    #[error("serde error: {0}")]
47    Serde(String),
48
49    /// An IO error (file, pipe, process).
50    #[error("io error: {0}")]
51    Io(String),
52
53    /// A schedule expression or trigger is invalid.
54    #[error("invalid schedule: {0}")]
55    InvalidSchedule(String),
56
57    /// A workflow graph contains a cycle.
58    #[error("workflow cycle: {0}")]
59    CycleDetected(String),
60
61    /// Enqueue rejected because the body is a near-duplicate.
62    #[error("duplicate work: {0}")]
63    DuplicateWork(String),
64
65    /// Input failed JSON schema validation for a skill/tool.
66    #[error("schema validation: {0}")]
67    SchemaValidation(String),
68
69    /// A memory port operation failed.
70    #[error("memory error: {0}")]
71    Memory(String),
72
73    /// A managed subprocess operation failed.
74    #[error("process error: {0}")]
75    Process(String),
76
77    /// A filesystem watcher operation failed.
78    #[error("watcher error: {0}")]
79    Watcher(String),
80
81    /// A cloud-dispatch adapter operation failed.
82    #[error("cloud dispatch error: {0}")]
83    CloudDispatch(String),
84
85    /// A catch-all for adapter-specific failures that do not fit above.
86    #[error("{0}")]
87    Other(String),
88}
89
90impl From<serde_json::Error> for SubstrateError {
91    fn from(e: serde_json::Error) -> Self {
92        SubstrateError::Serde(e.to_string())
93    }
94}
95
96/// Convenience result alias used across ports.
97pub type Result<T> = std::result::Result<T, SubstrateError>;