Skip to main content

ferro_projections/
error.rs

1use thiserror::Error;
2
3#[derive(Error, Debug)]
4pub enum Error {
5    #[error("service definition error: {0}")]
6    Definition(String),
7    #[error("validation error: {0}")]
8    Validation(String),
9    #[error("render error: {0}")]
10    Render(String),
11    #[error("serialization error: {0}")]
12    Serialization(#[from] serde_json::Error),
13    /// Caller supplied an empty intents slice — no render target exists.
14    /// Returned by render entry points instead of a silent `"unknown"`;
15    /// defined here so non-visual renderers can consume it. (D-08)
16    #[error("cannot render service with no intents")]
17    NoIntents,
18    /// An action selected for transition derivation declares no
19    /// `transition_trigger`, so no event-to-target mapping exists.
20    #[error("action '{0}' has no transition_trigger")]
21    NoTransitionTrigger(String),
22    /// Transition derivation was requested for a service with no state machine.
23    #[error("service '{0}' has no state machine")]
24    NoStateMachine(String),
25    /// An action's `transition_trigger` names an event that no declared
26    /// transition carries — the EXEC-04 drift condition, by construction.
27    #[error("action '{action}' transition_trigger '{event}' matches no declared transition")]
28    UndeclaredTransition { action: String, event: String },
29    /// A single event fans out to more than one target state across its
30    /// transitions; a `TransitionPlan` cannot pick one unambiguously.
31    #[error("event '{event}' fans out to multiple target states — ambiguous transition plan")]
32    AmbiguousTransition { event: String },
33    /// A CRUD verb was requested for a service that has not opted into it
34    /// (`.creatable(false)`, `.updatable(false)`, or `.deletable(false)`).
35    #[error("crud verb not enabled for service: {0}")]
36    VerbNotEnabled(String),
37}
38
39#[cfg(test)]
40mod tests {
41    use super::*;
42
43    #[test]
44    fn no_intents_error_message() {
45        let err = Error::NoIntents;
46        assert_eq!(err.to_string(), "cannot render service with no intents");
47    }
48}