1use std::sync::Arc;
2use thiserror::Error;
3
4#[derive(Debug, Error)]
5pub enum BeanError {
6 #[error("Bean not found: {0}")]
7 NotFound(String),
8
9 #[error("Bean method not found: {0}")]
10 MethodNotFound(String),
11
12 #[error("Parameter binding failed: {0}")]
13 BindingFailed(String),
14
15 #[error("Handler execution failed: {0}")]
16 ExecutionFailed(String),
17
18 #[error("Bean name must not be empty or whitespace-only: '{0}'")]
19 InvalidName(String),
20
21 #[error("Bean already registered: {0}")]
22 DuplicateName(String),
23}
24
25impl From<BeanError> for camel_api::CamelError {
26 fn from(err: BeanError) -> Self {
27 camel_api::CamelError::ProcessorErrorWithSource(err.to_string(), Arc::new(err))
28 }
29}
30
31#[cfg(test)]
32mod tests {
33 use super::*;
34
35 #[test]
36 fn test_bean_error_source_chain_preserved() {
37 let bean_err = BeanError::NotFound("myBean".to_string());
38 let camel_err: camel_api::CamelError = bean_err.into();
39
40 let source = std::error::Error::source(&camel_err);
42 assert!(
43 source.is_some(),
44 "CamelError::source() must return Some for BeanError conversion"
45 );
46
47 let source_ref = source.unwrap();
49 let msg = source_ref.to_string();
50 assert!(
51 msg.contains("myBean"),
52 "Source error message should contain 'myBean', got: {msg}"
53 );
54 }
55
56 #[test]
57 fn test_bean_error_to_camel_error_is_not_panic() {
58 let bean_err = BeanError::MethodNotFound("process".to_string());
60 let camel_err: camel_api::CamelError = bean_err.into();
61 assert!(matches!(
62 camel_err,
63 camel_api::CamelError::ProcessorErrorWithSource(_, _)
64 ));
65 }
66}