1#[derive(Debug, thiserror::Error)]
5pub enum FlozError {
6 #[error("Record not found")]
8 NotFound,
9
10 #[error("Unique constraint violated: {0}")]
12 UniqueViolation(String),
13
14 #[error("Foreign key constraint violated: {0}")]
16 ForeignKeyViolation(String),
17
18 #[error("Cannot save — entity has no primary key (use create() for new records)")]
20 UnsavedEntity,
21
22 #[error("Bulk insert row {row} is missing column `{column}`")]
24 MismatchedBulkInsertColumns {
25 row: usize,
26 column: String,
27 },
28
29 #[error("DELETE requires .where_() or .all() — refusing to delete all rows without explicit intent")]
31 UnguardedDelete,
32
33 #[error("UPDATE requires .where_() — refusing to update all rows without explicit intent")]
35 UnguardedUpdate,
36
37 #[error("Database error: {0}")]
39 Database(#[from] sqlx::Error),
40
41 #[error("Serialization error: {0}")]
43 Serialization(String),
44
45 #[error("Validation error: {0}")]
47 ValidationError(String),
48}
49
50#[cfg(test)]
51mod tests {
52 use super::*;
53
54 #[test]
55 fn error_display_not_found() {
56 let e = FlozError::NotFound;
57 assert_eq!(e.to_string(), "Record not found");
58 }
59
60 #[test]
61 fn error_display_unsaved_entity() {
62 let e = FlozError::UnsavedEntity;
63 assert!(e.to_string().contains("create()"));
64 }
65
66 #[test]
67 fn error_display_mismatched_bulk() {
68 let e = FlozError::MismatchedBulkInsertColumns {
69 row: 2,
70 column: "age".to_string(),
71 };
72 assert!(e.to_string().contains("row 2"));
73 assert!(e.to_string().contains("age"));
74 }
75
76 #[test]
77 fn error_display_unguarded_delete() {
78 let e = FlozError::UnguardedDelete;
79 assert!(e.to_string().contains(".where_()"));
80 assert!(e.to_string().contains(".all()"));
81 }
82
83 #[test]
84 fn error_display_unique_violation() {
85 let e = FlozError::UniqueViolation("users_email_key".into());
86 assert!(e.to_string().contains("users_email_key"));
87 }
88
89 #[test]
90 fn error_is_send_sync() {
91 fn assert_send<T: Send>() {}
92 fn assert_sync<T: Sync>() {}
93 assert_send::<FlozError>();
94 assert_sync::<FlozError>();
95 }
96}