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