Skip to main content

mlua_swarm/core/
errors.rs

1//! Engine error type.
2
3use crate::types::{Role, Verb};
4use thiserror::Error;
5
6/// All ways an engine operation can fail.
7#[derive(Debug, Error)]
8pub enum EngineError {
9    /// A required lock was busy and the operation gave up without retrying.
10    #[error("lock busy ({0})")]
11    LockBusy(&'static str),
12
13    /// A required lock was still busy after the configured retry budget was
14    /// exhausted.
15    #[error("lock busy after retry ({0})")]
16    LockBusyAfterRetry(&'static str),
17
18    /// The presented `CapToken`'s HMAC signature did not verify.
19    #[error("token signature invalid")]
20    BadSignature,
21
22    /// The presented `CapToken` is past its `expire_at`.
23    #[error("token expired")]
24    TokenExpired,
25
26    /// The presented `CapToken` has no uses left (`max_uses` budget spent).
27    #[error("token uses exhausted")]
28    TokenUsesExhausted,
29
30    /// No server-side record exists for the token. Carries the token
31    /// **fingerprint** (SHA-256 of the nonce, see `CapToken::fingerprint`)
32    /// — never the nonce itself, since this message can surface in HTTP
33    /// error bodies and logs (issue #14).
34    #[error("token not found in store (fp={0})")]
35    TokenNotFound(String),
36
37    /// The token's `Role` is not allow-listed for the requested `Verb` (see
38    /// `RoleVerbGate`).
39    #[error("role violation: role={role:?} verb={verb:?}")]
40    RoleViolation {
41        /// The role the token was minted for.
42        role: Role,
43        /// The verb that was rejected.
44        verb: Verb,
45    },
46
47    /// No task exists with the given id.
48    #[error("task not found: {0}")]
49    TaskNotFound(String),
50
51    /// No session is attached to the task.
52    #[error("session not found")]
53    SessionNotFound,
54
55    /// The resume key presented does not match any pending resume point.
56    #[error("resume key not found")]
57    ResumeKeyNotFound,
58
59    /// A generic named resource (other than task/session/token) was not
60    /// found.
61    #[error("resource not found: {0}")]
62    ResourceNotFound(String),
63
64    /// The requested state transition is not valid from the task's current
65    /// state.
66    #[error("invalid state transition: {0}")]
67    InvalidTransition(String),
68
69    /// Dispatching an attempt failed; the string carries the underlying
70    /// reason.
71    #[error("dispatch failed: {0}")]
72    DispatchFailed(String),
73
74    /// A poll operation exceeded its deadline without observing completion.
75    #[error("poll timeout")]
76    PollTimeout,
77
78    /// The task was cancelled.
79    #[error("cancelled")]
80    Cancelled,
81
82    /// A sub-task spawn would exceed the configured `max_spawn_depth`.
83    #[error("spawn depth exceeded: {current} >= max {max}")]
84    SpawnDepthExceeded {
85        /// The depth that would result from this spawn.
86        current: u32,
87        /// The configured maximum allowed depth.
88        max: u32,
89    },
90
91    /// The presented token is bound to a different task than the one
92    /// referenced by the call.
93    #[error("token task mismatch: token bound to {bound}, arg was {arg}")]
94    TokenTaskMismatch {
95        /// The task id the token is actually bound to.
96        bound: String,
97        /// The task id that was passed in the call.
98        arg: String,
99    },
100
101    /// Catch-all for invariant violations that don't have a dedicated
102    /// variant yet.
103    #[error("internal: {0}")]
104    Internal(String),
105}