Skip to main content

rustbridge_consumer/
error.rs

1//! Error types for the consumer crate.
2
3use rustbridge_core::LifecycleState;
4use thiserror::Error;
5
6/// Errors that can occur when loading or calling plugins.
7#[derive(Error, Debug)]
8pub enum ConsumerError {
9    /// Failed to load the shared library.
10    #[error("failed to load library: {0}")]
11    LibraryLoad(#[from] libloading::Error),
12
13    /// Plugin initialization failed.
14    #[error("plugin initialization failed: {0}")]
15    InitFailed(String),
16
17    /// Plugin call failed.
18    #[error("plugin call failed: {0}")]
19    CallFailed(#[from] rustbridge_core::PluginError),
20
21    /// Bundle loading error.
22    #[error("bundle error: {0}")]
23    Bundle(#[from] rustbridge_bundle::BundleError),
24
25    /// Failed to parse response from plugin.
26    #[error("invalid response: {0}")]
27    InvalidResponse(String),
28
29    /// Plugin is not in Active state.
30    #[error("plugin not active (state: {0:?})")]
31    NotActive(LifecycleState),
32
33    /// Plugin initialization returned null handle.
34    #[error("null handle returned from plugin")]
35    NullHandle,
36
37    /// Required FFI symbol not found in library.
38    #[error("missing symbol: {0}")]
39    MissingSymbol(String),
40
41    /// I/O error.
42    #[error("I/O error: {0}")]
43    Io(#[from] std::io::Error),
44
45    /// Serialization error.
46    #[error("serialization error: {0}")]
47    Serialization(#[from] serde_json::Error),
48}
49
50/// Result type for consumer operations.
51pub type ConsumerResult<T> = Result<T, ConsumerError>;
52
53#[cfg(test)]
54mod tests {
55    #![allow(non_snake_case)]
56
57    use super::*;
58
59    #[test]
60    fn ConsumerError___library_load___displays_message() {
61        // Create a libloading error by trying to load a nonexistent library
62        let lib_result: Result<libloading::Library, _> =
63            unsafe { libloading::Library::new("/nonexistent/library.so") };
64
65        let err = ConsumerError::from(lib_result.unwrap_err());
66
67        assert!(err.to_string().contains("failed to load library"));
68    }
69
70    #[test]
71    fn ConsumerError___init_failed___displays_message() {
72        let err = ConsumerError::InitFailed("config parse error".to_string());
73
74        assert_eq!(
75            err.to_string(),
76            "plugin initialization failed: config parse error"
77        );
78    }
79
80    #[test]
81    fn ConsumerError___not_active___displays_state() {
82        let err = ConsumerError::NotActive(LifecycleState::Stopped);
83
84        assert!(err.to_string().contains("Stopped"));
85    }
86
87    #[test]
88    fn ConsumerError___null_handle___displays_message() {
89        let err = ConsumerError::NullHandle;
90
91        assert_eq!(err.to_string(), "null handle returned from plugin");
92    }
93
94    #[test]
95    fn ConsumerError___missing_symbol___displays_symbol_name() {
96        let err = ConsumerError::MissingSymbol("plugin_init".to_string());
97
98        assert_eq!(err.to_string(), "missing symbol: plugin_init");
99    }
100
101    #[test]
102    fn ConsumerError___invalid_response___displays_reason() {
103        let err = ConsumerError::InvalidResponse("malformed JSON".to_string());
104
105        assert_eq!(err.to_string(), "invalid response: malformed JSON");
106    }
107}