rocketmq_error/unified/
tools.rs1use thiserror::Error;
20
21#[derive(Debug, Error)]
23pub enum ToolsError {
24 #[error("Topic '{topic}' not found")]
29 TopicNotFound { topic: String },
30
31 #[error("Topic '{topic}' already exists")]
33 TopicAlreadyExists { topic: String },
34
35 #[error("Invalid topic configuration: {reason}")]
37 TopicInvalid { reason: String },
38
39 #[error("Cluster '{cluster}' not found")]
44 ClusterNotFound { cluster: String },
45
46 #[error("Invalid cluster configuration: {reason}")]
48 ClusterInvalid { reason: String },
49
50 #[error("Broker '{broker}' not found")]
55 BrokerNotFound { broker: String },
56
57 #[error("Broker '{broker}' is offline")]
59 BrokerOffline { broker: String },
60
61 #[error("Consumer group '{group}' not found")]
66 ConsumerGroupNotFound { group: String },
67
68 #[error("Consumer '{consumer}' is offline")]
70 ConsumerOffline { consumer: String },
71
72 #[error("NameServer '{addr}' is unreachable")]
77 NameServerUnreachable { addr: String },
78
79 #[error("Invalid NameServer configuration: {reason}")]
81 NameServerConfigInvalid { reason: String },
82
83 #[error("Invalid configuration for '{field}': {reason}")]
88 InvalidConfiguration { field: String, reason: String },
89
90 #[error("Missing required field: '{field}'")]
92 MissingRequiredField { field: String },
93
94 #[error("Validation failed for '{field}': {reason}")]
99 ValidationError { field: String, reason: String },
100
101 #[error("Validation error: {message}")]
103 ValidationFailed { message: String },
104
105 #[error("Permission denied for operation: {operation}")]
110 PermissionDenied { operation: String },
111
112 #[error("Invalid permission value: {value}, allowed values: {}", .allowed.iter().map(|v| v.to_string()).collect::<Vec<_>>().join(", "))]
114 InvalidPermission { value: i32, allowed: Vec<i32> },
115
116 #[error("Operation '{operation}' timed out after {duration_ms}ms")]
121 OperationTimeout { operation: String, duration_ms: u64 },
122
123 #[error("Internal error: {message}")]
125 Internal { message: String },
126}
127
128impl ToolsError {
129 #[inline]
135 pub fn topic_not_found(topic: impl Into<String>) -> Self {
136 Self::TopicNotFound { topic: topic.into() }
137 }
138
139 #[inline]
141 pub fn topic_already_exists(topic: impl Into<String>) -> Self {
142 Self::TopicAlreadyExists { topic: topic.into() }
143 }
144
145 #[inline]
147 pub fn cluster_not_found(cluster: impl Into<String>) -> Self {
148 Self::ClusterNotFound {
149 cluster: cluster.into(),
150 }
151 }
152
153 #[inline]
155 pub fn broker_not_found(broker: impl Into<String>) -> Self {
156 Self::BrokerNotFound { broker: broker.into() }
157 }
158
159 #[inline]
161 pub fn validation_error(field: impl Into<String>, reason: impl Into<String>) -> Self {
162 Self::ValidationError {
163 field: field.into(),
164 reason: reason.into(),
165 }
166 }
167
168 #[inline]
170 pub fn nameserver_unreachable(addr: impl Into<String>) -> Self {
171 Self::NameServerUnreachable { addr: addr.into() }
172 }
173
174 #[inline]
176 pub fn nameserver_config_invalid(reason: impl Into<String>) -> Self {
177 Self::NameServerConfigInvalid { reason: reason.into() }
178 }
179
180 #[inline]
182 pub fn internal(message: impl Into<String>) -> Self {
183 Self::Internal {
184 message: message.into(),
185 }
186 }
187}
188
189#[cfg(test)]
190mod tests {
191 use super::*;
192
193 #[test]
194 fn test_topic_management_errors() {
195 let err = ToolsError::topic_not_found("TestTopic");
196 assert_eq!(err.to_string(), "Topic 'TestTopic' not found");
197
198 let err = ToolsError::topic_already_exists("TestTopic");
199 assert_eq!(err.to_string(), "Topic 'TestTopic' already exists");
200
201 let err = ToolsError::TopicInvalid {
202 reason: "invalid partitions".to_string(),
203 };
204 assert_eq!(err.to_string(), "Invalid topic configuration: invalid partitions");
205 }
206
207 #[test]
208 fn test_cluster_management_errors() {
209 let err = ToolsError::cluster_not_found("TestCluster");
210 assert_eq!(err.to_string(), "Cluster 'TestCluster' not found");
211
212 let err = ToolsError::ClusterInvalid {
213 reason: "missing brokers".to_string(),
214 };
215 assert_eq!(err.to_string(), "Invalid cluster configuration: missing brokers");
216 }
217
218 #[test]
219 fn test_broker_management_errors() {
220 let err = ToolsError::broker_not_found("broker-a");
221 assert_eq!(err.to_string(), "Broker 'broker-a' not found");
222
223 let err = ToolsError::BrokerOffline {
224 broker: "broker-a".to_string(),
225 };
226 assert_eq!(err.to_string(), "Broker 'broker-a' is offline");
227 }
228
229 #[test]
230 fn test_consumer_management_errors() {
231 let err = ToolsError::ConsumerGroupNotFound {
232 group: "test-group".to_string(),
233 };
234 assert_eq!(err.to_string(), "Consumer group 'test-group' not found");
235
236 let err = ToolsError::ConsumerOffline {
237 consumer: "consumer-1".to_string(),
238 };
239 assert_eq!(err.to_string(), "Consumer 'consumer-1' is offline");
240 }
241
242 #[test]
243 fn test_nameserver_management_errors() {
244 let err = ToolsError::nameserver_unreachable("127.0.0.1:9876");
245 assert_eq!(err.to_string(), "NameServer '127.0.0.1:9876' is unreachable");
246
247 let err = ToolsError::nameserver_config_invalid("missing nameserver");
248 assert_eq!(err.to_string(), "Invalid NameServer configuration: missing nameserver");
249 }
250
251 #[test]
252 fn test_configuration_errors() {
253 let err = ToolsError::InvalidConfiguration {
254 field: "name_server".to_string(),
255 reason: "missing nameserver".to_string(),
256 };
257 assert_eq!(
258 err.to_string(),
259 "Invalid configuration for 'name_server': missing nameserver"
260 );
261
262 let err = ToolsError::MissingRequiredField {
263 field: "topic".to_string(),
264 };
265 assert_eq!(err.to_string(), "Missing required field: 'topic'");
266 }
267
268 #[test]
269 fn test_validation_errors() {
270 let err = ToolsError::validation_error("topic_name", "name too long");
271 assert_eq!(err.to_string(), "Validation failed for 'topic_name': name too long");
272
273 let err = ToolsError::ValidationFailed {
274 message: "generic validation error".to_string(),
275 };
276 assert_eq!(err.to_string(), "Validation error: generic validation error");
277 }
278
279 #[test]
280 fn test_permission_errors() {
281 let err = ToolsError::PermissionDenied {
282 operation: "createTopic".to_string(),
283 };
284 assert_eq!(err.to_string(), "Permission denied for operation: createTopic");
285
286 let err = ToolsError::InvalidPermission {
287 value: 1,
288 allowed: vec![2, 4, 6],
289 };
290 assert!(err.to_string().contains("Invalid permission value: 1"));
291 assert!(err.to_string().contains("2, 4, 6"));
292 }
293
294 #[test]
295 fn test_operation_errors() {
296 let err = ToolsError::OperationTimeout {
297 operation: "createTopic".to_string(),
298 duration_ms: 5000,
299 };
300 assert!(err
301 .to_string()
302 .contains("Operation 'createTopic' timed out after 5000ms"));
303
304 let err = ToolsError::internal("unexpected error");
305 assert!(err.to_string().contains("Internal error: unexpected error"));
306 }
307}