1use thiserror::Error;
2
3#[derive(Debug, Clone, Error)]
5#[non_exhaustive]
6pub enum CamelError {
7 #[error("Component not found: {0}")]
8 ComponentNotFound(String),
9
10 #[error("Endpoint creation failed: {0}")]
11 EndpointCreationFailed(String),
12
13 #[error("Processor error: {0}")]
14 ProcessorError(String),
15
16 #[error("Type conversion failed: {0}")]
17 TypeConversionFailed(String),
18
19 #[error("Invalid URI: {0}")]
20 InvalidUri(String),
21
22 #[error("Channel closed")]
23 ChannelClosed,
24
25 #[error("Route error: {0}")]
26 RouteError(String),
27
28 #[error("IO error: {0}")]
29 Io(String),
30
31 #[error("Dead letter channel failed: {0}")]
32 DeadLetterChannelFailed(String),
33
34 #[error("Circuit breaker open: {0}")]
35 CircuitOpen(String),
36
37 #[error("HTTP operation failed: {status_code} {status_text}")]
38 HttpOperationFailed {
39 status_code: u16,
40 status_text: String,
41 response_body: Option<String>,
42 },
43
44 #[error("Exchange stopped by Stop EIP")]
45 Stopped,
46
47 #[error("Configuration error: {0}")]
48 Config(String),
49
50 #[error("Body stream has already been consumed")]
51 AlreadyConsumed,
52
53 #[error("Stream size exceeded limit: {0}")]
54 StreamLimitExceeded(usize),
55}
56
57impl From<std::io::Error> for CamelError {
58 fn from(err: std::io::Error) -> Self {
59 CamelError::Io(err.to_string())
60 }
61}
62
63#[cfg(test)]
64mod tests {
65 use super::*;
66
67 #[test]
68 fn test_http_operation_failed_display() {
69 let err = CamelError::HttpOperationFailed {
70 status_code: 404,
71 status_text: "Not Found".to_string(),
72 response_body: Some("page not found".to_string()),
73 };
74 let msg = format!("{err}");
75 assert!(msg.contains("404"));
76 assert!(msg.contains("Not Found"));
77 }
78
79 #[test]
80 fn test_http_operation_failed_clone() {
81 let err = CamelError::HttpOperationFailed {
82 status_code: 500,
83 status_text: "Internal Server Error".to_string(),
84 response_body: None,
85 };
86 let cloned = err.clone();
87 assert!(matches!(
88 cloned,
89 CamelError::HttpOperationFailed {
90 status_code: 500,
91 ..
92 }
93 ));
94 }
95
96 #[test]
97 fn test_stopped_variant_exists_and_is_clone() {
98 let err = CamelError::Stopped;
99 let cloned = err.clone();
100 assert!(matches!(cloned, CamelError::Stopped));
101 assert_eq!(format!("{err}"), "Exchange stopped by Stop EIP");
102 }
103}