1use thiserror::Error;
7use uuid::Uuid;
8
9use crate::entities::RunStatus;
10
11#[derive(Debug, Error)]
23pub enum StoreError {
24 #[error("run not found: {0}")]
26 RunNotFound(Uuid),
27
28 #[error("step not found: {0}")]
30 StepNotFound(Uuid),
31
32 #[error("invalid status transition: {from} -> {to}")]
34 InvalidTransition {
35 from: RunStatus,
37 to: RunStatus,
39 },
40
41 #[error("email already exists: {0}")]
43 DuplicateEmail(String),
44
45 #[error("username already exists: {0}")]
47 DuplicateUsername(String),
48
49 #[error("user not found: {0}")]
51 UserNotFound(Uuid),
52
53 #[error("database error: {0}")]
55 Database(String),
56
57 #[error("serialization error: {0}")]
59 Serialization(#[from] serde_json::Error),
60
61 #[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}