Skip to main content

ironflow_store/
error.rs

1//! Storage error types.
2//!
3//! [`StoreError`] covers all failure modes for [`RunStore`](crate::store::RunStore)
4//! implementations, from missing records to invalid FSM transitions.
5
6use thiserror::Error;
7use uuid::Uuid;
8
9use crate::entities::RunStatus;
10
11/// Errors produced by [`RunStore`](crate::store::RunStore) operations.
12///
13/// # Examples
14///
15/// ```
16/// use ironflow_store::error::StoreError;
17/// use uuid::Uuid;
18///
19/// let err = StoreError::RunNotFound(Uuid::nil());
20/// assert!(err.to_string().contains("run not found"));
21/// ```
22#[derive(Debug, Error)]
23pub enum StoreError {
24    /// The requested run does not exist.
25    #[error("run not found: {0}")]
26    RunNotFound(Uuid),
27
28    /// The requested step does not exist.
29    #[error("step not found: {0}")]
30    StepNotFound(Uuid),
31
32    /// Attempted an illegal FSM transition.
33    #[error("invalid status transition: {from} -> {to}")]
34    InvalidTransition {
35        /// Current status.
36        from: RunStatus,
37        /// Attempted target status.
38        to: RunStatus,
39    },
40
41    /// Email is already taken by another user.
42    #[error("email already exists: {0}")]
43    DuplicateEmail(String),
44
45    /// Username is already taken by another user.
46    #[error("username already exists: {0}")]
47    DuplicateUsername(String),
48
49    /// The requested user does not exist.
50    #[error("user not found: {0}")]
51    UserNotFound(Uuid),
52
53    /// A database or I/O error from the backing store.
54    #[error("database error: {0}")]
55    Database(String),
56
57    /// JSON serialization or deserialization failed.
58    #[error("serialization error: {0}")]
59    Serialization(#[from] serde_json::Error),
60
61    /// A cryptographic operation failed (encryption or decryption).
62    #[error("crypto error: {0}")]
63    Crypto(String),
64}
65
66#[cfg(test)]
67mod tests {
68    use super::*;
69
70    #[test]
71    fn run_not_found_display() {
72        let id = Uuid::nil();
73        let err = StoreError::RunNotFound(id);
74        assert_eq!(err.to_string(), format!("run not found: {id}"));
75    }
76
77    #[test]
78    fn step_not_found_display() {
79        let id = Uuid::nil();
80        let err = StoreError::StepNotFound(id);
81        assert_eq!(err.to_string(), format!("step not found: {id}"));
82    }
83
84    #[test]
85    fn invalid_transition_display() {
86        let err = StoreError::InvalidTransition {
87            from: RunStatus::Pending,
88            to: RunStatus::Completed,
89        };
90        assert!(err.to_string().contains("Pending"));
91        assert!(err.to_string().contains("Completed"));
92    }
93
94    #[test]
95    fn database_error_display() {
96        let err = StoreError::Database("connection refused".to_string());
97        assert!(err.to_string().contains("connection refused"));
98    }
99
100    #[test]
101    fn serialization_error_from_serde() {
102        let serde_err = serde_json::from_str::<String>("not json").unwrap_err();
103        let err = StoreError::from(serde_err);
104        assert!(err.to_string().contains("serialization error"));
105    }
106}