Skip to main content

camel_api/
error.rs

1use thiserror::Error;
2
3/// Core error type for the Camel framework.
4#[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 {method} {url} failed: {status_code} {status_text}")]
38    HttpOperationFailed {
39        method: String,
40        url: String,
41        status_code: u16,
42        status_text: String,
43        response_body: Option<String>,
44    },
45
46    #[error("Exchange stopped by Stop EIP")]
47    Stopped,
48
49    #[error("Configuration error: {0}")]
50    Config(String),
51
52    #[error("Body stream has already been consumed")]
53    AlreadyConsumed,
54
55    #[error("Stream size exceeded limit: {0}")]
56    StreamLimitExceeded(usize),
57}
58
59impl From<std::io::Error> for CamelError {
60    fn from(err: std::io::Error) -> Self {
61        CamelError::Io(err.to_string())
62    }
63}
64
65#[cfg(test)]
66mod tests {
67    use super::*;
68
69    #[test]
70    fn test_http_operation_failed_display() {
71        let err = CamelError::HttpOperationFailed {
72            method: "GET".to_string(),
73            url: "https://example.com/test".to_string(),
74            status_code: 404,
75            status_text: "Not Found".to_string(),
76            response_body: Some("page not found".to_string()),
77        };
78        let msg = format!("{err}");
79        assert!(msg.contains("404"));
80        assert!(msg.contains("Not Found"));
81    }
82
83    #[test]
84    fn test_http_operation_failed_clone() {
85        let err = CamelError::HttpOperationFailed {
86            method: "POST".to_string(),
87            url: "https://api.example.com/users".to_string(),
88            status_code: 500,
89            status_text: "Internal Server Error".to_string(),
90            response_body: None,
91        };
92        let cloned = err.clone();
93        assert!(matches!(
94            cloned,
95            CamelError::HttpOperationFailed {
96                status_code: 500,
97                ..
98            }
99        ));
100    }
101
102    #[test]
103    fn test_stopped_variant_exists_and_is_clone() {
104        let err = CamelError::Stopped;
105        let cloned = err.clone();
106        assert!(matches!(cloned, CamelError::Stopped));
107        assert_eq!(format!("{err}"), "Exchange stopped by Stop EIP");
108    }
109}