use alloc::string::String;
use super::types::ManifestError;
#[derive(Debug)]
pub enum PluginError {
CompilationFailed(String),
InstantiationFailed(String),
InitFailed(i32),
InvalidManifest(ManifestError),
NotFound(String),
AlreadyLoaded(String),
ExecutionFailed(String),
ResourceLimitExceeded(String),
PermissionDenied(String),
MemoryError(String),
MissingExport(String),
InvalidSignature(String),
PluginReturnedError(i32),
IoError(String),
HookNotImplemented,
Internal(String),
}
impl PluginError {
pub fn message(&self) -> String {
match self {
PluginError::CompilationFailed(msg) => {
alloc::format!("WASM compilation failed: {}", msg)
}
PluginError::InstantiationFailed(msg) => {
alloc::format!("WASM instantiation failed: {}", msg)
}
PluginError::InitFailed(code) => {
alloc::format!("Plugin initialization failed with code {}", code)
}
PluginError::InvalidManifest(e) => {
alloc::format!("Invalid plugin manifest: {:?}", e)
}
PluginError::NotFound(name) => {
alloc::format!("Plugin not found: {}", name)
}
PluginError::AlreadyLoaded(name) => {
alloc::format!("Plugin already loaded: {}", name)
}
PluginError::ExecutionFailed(msg) => {
alloc::format!("Plugin execution failed: {}", msg)
}
PluginError::ResourceLimitExceeded(resource) => {
alloc::format!("Resource limit exceeded: {}", resource)
}
PluginError::PermissionDenied(perm) => {
alloc::format!("Permission denied: {}", perm)
}
PluginError::MemoryError(msg) => {
alloc::format!("WASM memory error: {}", msg)
}
PluginError::MissingExport(name) => {
alloc::format!("Missing required export: {}", name)
}
PluginError::InvalidSignature(name) => {
alloc::format!("Invalid function signature: {}", name)
}
PluginError::PluginReturnedError(code) => {
alloc::format!("Plugin returned error code {}", code)
}
PluginError::IoError(msg) => {
alloc::format!("I/O error: {}", msg)
}
PluginError::HookNotImplemented => "Hook not implemented".into(),
PluginError::Internal(msg) => {
alloc::format!("Internal error: {}", msg)
}
}
}
pub fn is_recoverable(&self) -> bool {
matches!(
self,
PluginError::ResourceLimitExceeded(_)
| PluginError::PluginReturnedError(_)
| PluginError::HookNotImplemented
)
}
}
impl From<ManifestError> for PluginError {
fn from(e: ManifestError) -> Self {
PluginError::InvalidManifest(e)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_error_messages() {
let err = PluginError::NotFound("test-plugin".into());
assert!(err.message().contains("test-plugin"));
let err = PluginError::InitFailed(-1);
assert!(err.message().contains("-1"));
let err = PluginError::ResourceLimitExceeded("memory".into());
assert!(err.message().contains("memory"));
}
#[test]
fn test_is_recoverable() {
assert!(PluginError::ResourceLimitExceeded("memory".into()).is_recoverable());
assert!(PluginError::PluginReturnedError(1).is_recoverable());
assert!(PluginError::HookNotImplemented.is_recoverable());
assert!(!PluginError::CompilationFailed("bad wasm".into()).is_recoverable());
assert!(!PluginError::InitFailed(-1).is_recoverable());
}
#[test]
fn test_from_manifest_error() {
let manifest_err = ManifestError::MissingField("name");
let plugin_err: PluginError = manifest_err.into();
assert!(matches!(plugin_err, PluginError::InvalidManifest(_)));
}
}