version_migrate/
errors.rs1use thiserror::Error;
4
5#[derive(Error, Debug)]
7pub enum MigrationError {
8 #[error("Failed to deserialize: {0}")]
10 DeserializationError(String),
11
12 #[error("Failed to serialize: {0}")]
14 SerializationError(String),
15
16 #[error("Entity '{0}' not found")]
18 EntityNotFound(String),
19
20 #[error("No migration path defined for entity '{entity}' version '{version}'")]
22 MigrationPathNotDefined {
23 entity: String,
25 version: String,
27 },
28
29 #[error("Migration failed from '{from}' to '{to}': {error}")]
31 MigrationStepFailed {
32 from: String,
34 to: String,
36 error: String,
38 },
39
40 #[error("Circular migration path detected in entity '{entity}': {path}")]
42 CircularMigrationPath {
43 entity: String,
45 path: String,
47 },
48
49 #[error("Invalid version order in entity '{entity}': '{from}' -> '{to}' (versions must increase according to semver)")]
51 InvalidVersionOrder {
52 entity: String,
54 from: String,
56 to: String,
58 },
59}
60
61#[cfg(test)]
62mod tests {
63 use super::*;
64
65 #[test]
66 fn test_error_display_deserialization() {
67 let err = MigrationError::DeserializationError("invalid JSON".to_string());
68 let display = format!("{}", err);
69 assert!(display.contains("Failed to deserialize"));
70 assert!(display.contains("invalid JSON"));
71 }
72
73 #[test]
74 fn test_error_display_serialization() {
75 let err = MigrationError::SerializationError("invalid data".to_string());
76 let display = format!("{}", err);
77 assert!(display.contains("Failed to serialize"));
78 assert!(display.contains("invalid data"));
79 }
80
81 #[test]
82 fn test_error_display_entity_not_found() {
83 let err = MigrationError::EntityNotFound("user".to_string());
84 let display = format!("{}", err);
85 assert!(display.contains("Entity 'user' not found"));
86 }
87
88 #[test]
89 fn test_error_display_migration_path_not_defined() {
90 let err = MigrationError::MigrationPathNotDefined {
91 entity: "task".to_string(),
92 version: "2.0.0".to_string(),
93 };
94 let display = format!("{}", err);
95 assert!(display.contains("No migration path defined"));
96 assert!(display.contains("task"));
97 assert!(display.contains("2.0.0"));
98 }
99
100 #[test]
101 fn test_error_display_migration_step_failed() {
102 let err = MigrationError::MigrationStepFailed {
103 from: "1.0.0".to_string(),
104 to: "2.0.0".to_string(),
105 error: "field missing".to_string(),
106 };
107 let display = format!("{}", err);
108 assert!(display.contains("Migration failed"));
109 assert!(display.contains("1.0.0"));
110 assert!(display.contains("2.0.0"));
111 assert!(display.contains("field missing"));
112 }
113
114 #[test]
115 fn test_error_debug() {
116 let err = MigrationError::EntityNotFound("test".to_string());
117 let debug = format!("{:?}", err);
118 assert!(debug.contains("EntityNotFound"));
119 }
120
121 #[test]
122 fn test_error_is_std_error() {
123 let err = MigrationError::DeserializationError("test".to_string());
124 let _: &dyn std::error::Error = &err;
126 }
127
128 #[test]
129 fn test_error_display_circular_migration_path() {
130 let err = MigrationError::CircularMigrationPath {
131 entity: "task".to_string(),
132 path: "1.0.0 -> 2.0.0 -> 1.0.0".to_string(),
133 };
134 let display = format!("{}", err);
135 assert!(display.contains("Circular migration path"));
136 assert!(display.contains("task"));
137 assert!(display.contains("1.0.0 -> 2.0.0 -> 1.0.0"));
138 }
139
140 #[test]
141 fn test_error_display_invalid_version_order() {
142 let err = MigrationError::InvalidVersionOrder {
143 entity: "task".to_string(),
144 from: "2.0.0".to_string(),
145 to: "1.0.0".to_string(),
146 };
147 let display = format!("{}", err);
148 assert!(display.contains("Invalid version order"));
149 assert!(display.contains("task"));
150 assert!(display.contains("2.0.0"));
151 assert!(display.contains("1.0.0"));
152 assert!(display.contains("must increase"));
153 }
154}