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("lease lost on run {run_id}")]
58 LeaseLost {
59 run_id: Uuid,
61 held_by: Option<String>,
63 },
64
65 #[error("artifact {name:?} already exists on step {step_id}")]
67 DuplicateArtifact {
68 step_id: Uuid,
70 name: String,
72 },
73
74 #[error("schedule not found: {0}")]
76 ScheduleNotFound(Uuid),
77
78 #[error("approval delegation not found: {0}")]
80 DelegationNotFound(Uuid),
81
82 #[error("provider account not found: {0}")]
84 ProviderAccountNotFound(Uuid),
85
86 #[error("provider account already exists: {0}")]
88 DuplicateProviderAccount(String),
89
90 #[error("database error: {0}")]
92 Database(String),
93
94 #[error("serialization error: {0}")]
96 Serialization(#[from] serde_json::Error),
97
98 #[error("crypto error: {0}")]
100 Crypto(String),
101}
102
103#[cfg(test)]
104mod tests {
105 use super::*;
106
107 #[test]
108 fn run_not_found_display() {
109 let id = Uuid::nil();
110 let err = StoreError::RunNotFound(id);
111 assert_eq!(err.to_string(), format!("run not found: {id}"));
112 }
113
114 #[test]
115 fn step_not_found_display() {
116 let id = Uuid::nil();
117 let err = StoreError::StepNotFound(id);
118 assert_eq!(err.to_string(), format!("step not found: {id}"));
119 }
120
121 #[test]
122 fn invalid_transition_display() {
123 let err = StoreError::InvalidTransition {
124 from: RunStatus::Pending,
125 to: RunStatus::Completed,
126 };
127 assert!(err.to_string().contains("Pending"));
128 assert!(err.to_string().contains("Completed"));
129 }
130
131 #[test]
132 fn delegation_not_found_display() {
133 let id = Uuid::nil();
134 let err = StoreError::DelegationNotFound(id);
135 assert_eq!(
136 err.to_string(),
137 format!("approval delegation not found: {id}")
138 );
139 }
140
141 #[test]
142 fn database_error_display() {
143 let err = StoreError::Database("connection refused".to_string());
144 assert!(err.to_string().contains("connection refused"));
145 }
146
147 #[test]
148 fn serialization_error_from_serde() {
149 let serde_err = serde_json::from_str::<String>("not json").unwrap_err();
150 let err = StoreError::from(serde_err);
151 assert!(err.to_string().contains("serialization error"));
152 }
153}