Skip to main content

camel_component_validator/
error.rs

1use std::sync::Arc;
2
3use thiserror::Error;
4
5use crate::proto;
6
7#[derive(Error, Debug, Clone)]
8pub enum ValidatorError {
9    #[error("{0}")]
10    Endpoint(String),
11    #[error("{0}")]
12    Validation(String),
13    #[error("{message}")]
14    Transport {
15        message: String,
16        #[source]
17        source: Option<Arc<dyn std::error::Error + Send + Sync>>,
18    },
19    #[error("{0}")]
20    UnsupportedMode(&'static str),
21    #[error("{message}")]
22    CompilationFailed {
23        message: String,
24        #[source]
25        source: Option<Arc<dyn std::error::Error + Send + Sync>>,
26    },
27    #[error("payload too large: {actual} bytes exceeds limit of {limit} bytes")]
28    PayloadTooLarge { actual: usize, limit: usize },
29}
30
31impl ValidatorError {
32    pub fn endpoint(msg: impl Into<String>) -> Self {
33        Self::Endpoint(msg.into())
34    }
35
36    pub fn validation(msg: impl Into<String>) -> Self {
37        Self::Validation(msg.into())
38    }
39
40    pub fn transport_with_source(
41        msg: impl Into<String>,
42        source: impl std::error::Error + Send + Sync + 'static,
43    ) -> Self {
44        Self::Transport {
45            message: msg.into(),
46            source: Some(Arc::new(source)),
47        }
48    }
49
50    pub fn from_bridge_error(err: &proto::BridgeError) -> Self {
51        let msg = err.message.clone();
52        match proto::bridge_error::Kind::try_from(err.kind)
53            .unwrap_or(proto::bridge_error::Kind::Unknown)
54        {
55            proto::bridge_error::Kind::CompilationFailed => Self::CompilationFailed {
56                message: msg,
57                source: None,
58            },
59            proto::bridge_error::Kind::ValidationFailed => Self::Validation(msg),
60            proto::bridge_error::Kind::Unknown
61            | proto::bridge_error::Kind::InvalidInput
62            | proto::bridge_error::Kind::TransformFailed
63            | proto::bridge_error::Kind::ResourceNotFound
64            | proto::bridge_error::Kind::SecurityViolation
65            | proto::bridge_error::Kind::Internal => Self::Transport {
66                message: msg,
67                source: None,
68            },
69        }
70    }
71
72    pub fn to_endpoint_error(&self) -> camel_component_api::CamelError {
73        camel_component_api::CamelError::EndpointCreationFailed(self.to_string())
74    }
75
76    pub fn to_processor_error(&self) -> camel_component_api::CamelError {
77        camel_component_api::CamelError::ProcessorError(self.to_string())
78    }
79}
80
81#[cfg(test)]
82mod tests {
83    use super::*;
84
85    #[test]
86    fn transport_variant_preserves_source_chain() {
87        let inner = std::io::Error::other("socket closed");
88        let err = ValidatorError::transport_with_source("rpc failed", inner);
89        let source = std::error::Error::source(&err);
90        assert!(source.is_some());
91        assert!(source.unwrap().to_string().contains("socket closed"));
92    }
93}