Skip to main content

mockforge_plugin_core/
error.rs

1//! Plugin error types and result handling
2//!
3//! Re-exports the canonical [`PluginError`] from [`crate::types`] and provides
4//! the crate-level [`Result`] alias along with additional convenience constructors.
5
6pub use crate::types::PluginError;
7
8/// Plugin system result type
9pub type Result<T> = std::result::Result<T, PluginError>;
10
11/// Additional convenience constructors for PluginError.
12///
13/// The core constructors (`execution`, `security`, `wasm`) live in `types.rs`.
14impl PluginError {
15    /// Create a load error
16    pub fn load<S: Into<String>>(message: S) -> Self {
17        Self::InternalError {
18            message: format!("Plugin loading error: {}", message.into()),
19        }
20    }
21
22    /// Create a configuration error (field + message)
23    pub fn config<S: Into<String>>(field: S, message: S) -> Self {
24        Self::ConfigurationError {
25            message: format!("{}: {}", field.into(), message.into()),
26        }
27    }
28
29    /// Create a compatibility error
30    pub fn compatibility<S: Into<String>>(reason: S) -> Self {
31        Self::InternalError {
32            message: format!("Compatibility error: {}", reason.into()),
33        }
34    }
35
36    /// Create a communication error
37    pub fn communication<S: Into<String>>(message: S) -> Self {
38        Self::InternalError {
39            message: format!("Communication error: {}", message.into()),
40        }
41    }
42
43    /// Create a timeout error
44    pub fn timeout(_timeout_ms: u64) -> Self {
45        Self::Timeout
46    }
47
48    /// Create a manifest error
49    pub fn manifest<S: Into<String>>(message: S) -> Self {
50        Self::InternalError {
51            message: format!("Invalid manifest: {}", message.into()),
52        }
53    }
54
55    /// Create a dependency error
56    pub fn dependency<S: Into<String>>(dependency: S, message: S) -> Self {
57        Self::DependencyMissing {
58            dependency: format!("{}: {}", dependency.into(), message.into()),
59        }
60    }
61
62    /// Create a system error
63    pub fn system<S: Into<String>>(message: S) -> Self {
64        Self::InternalError {
65            message: message.into(),
66        }
67    }
68
69    /// Check if this is a security-related error
70    pub fn is_security_error(&self) -> bool {
71        matches!(self, Self::SecurityViolation { .. })
72    }
73
74    /// Check if this is a timeout error
75    pub fn is_timeout_error(&self) -> bool {
76        matches!(self, Self::Timeout)
77    }
78}
79
80#[cfg(test)]
81mod tests {
82    use super::*;
83
84    #[test]
85    fn test_load_error() {
86        let err = PluginError::load("failed to load plugin");
87        assert!(err.to_string().contains("failed to load plugin"));
88    }
89
90    #[test]
91    fn test_execution_error() {
92        let err = PluginError::execution("execution failed");
93        assert!(matches!(err, PluginError::ExecutionError { .. }));
94    }
95
96    #[test]
97    fn test_security_error() {
98        let err = PluginError::security("unauthorized access");
99        assert!(matches!(err, PluginError::SecurityViolation { .. }));
100    }
101
102    #[test]
103    fn test_timeout_error() {
104        let err = PluginError::timeout(5000);
105        assert!(err.is_timeout_error());
106    }
107
108    #[test]
109    fn test_system_error() {
110        let err = PluginError::system("internal failure");
111        assert!(err.to_string().contains("internal failure"));
112    }
113
114    #[test]
115    fn test_is_security_error() {
116        let err = PluginError::security("test");
117        assert!(err.is_security_error());
118    }
119}