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>;