//! Error handling for model merging operations use thiserror::Error; /// Result type for model merging operations pub type Result = std::result::Result; /// Comprehensive error types for model merging #[derive(Error, Debug)] pub enum MergeError { #[error("Model loading failed: {message}")] ModelLoadError { message: String }, #[error("Model compatibility error: {details}")] CompatibilityError { details: String }, #[error("Parameter mismatch: expected {expected}, found {found}")] ParameterMismatch { expected: String, found: String }, #[error("Architecture incompatibility: {model1} vs {model2}")] ArchitectureIncompatible { model1: String, model2: String }, #[error("Merge algorithm failed: {algorithm} - {reason}")] AlgorithmError { algorithm: String, reason: String }, #[error("Expert selection failed: {reason}")] ExpertSelectionError { reason: String }, #[error("Conflict resolution failed: {conflicts} conflicts unresolved")] ConflictResolutionError { conflicts: usize }, #[error("Validation failed: {} validation checks failed", checks.len())] ValidationError { checks: Vec }, #[error("Performance evaluation error: {metric} computation failed")] EvaluationError { metric: String }, #[error("Configuration error: {field} - {message}")] ConfigError { field: String, message: String }, #[error("Memory allocation error: {size_mb}MB required")] MemoryError { size_mb: usize }, #[error("GPU operation failed: {operation}")] GpuError { operation: String }, #[error("Numerical instability detected: {operation}")] NumericalError { operation: String }, #[error("File I/O error: {path}")] IoError { path: String, #[source] source: std::io::Error, }, #[error("Serialization error")] SerializationError(#[from] bincode::Error), #[error("JSON error")] JsonError(#[from] serde_json::Error), #[error("TOML error")] TomlError(#[from] toml::de::Error), #[error("Async runtime error")] AsyncError(#[from] tokio::task::JoinError), #[error("Thread pool error")] ThreadPoolError(String), #[error("Timeout error: operation took longer than {timeout_ms}ms")] TimeoutError { timeout_ms: u64 }, #[error("Resource exhaustion: {resource}")] ResourceExhausted { resource: String }, #[error("Model format not supported: {format}")] UnsupportedFormat { format: String }, #[error("Feature not implemented: {feature}")] NotImplemented { feature: String }, #[error("Internal error: {message}")] Internal { message: String }, } impl MergeError { /// Create a model loading error pub fn model_load>(message: S) -> Self { Self::ModelLoadError { message: message.into(), } } /// Create a compatibility error pub fn compatibility>(details: S) -> Self { Self::CompatibilityError { details: details.into(), } } /// Create a parameter mismatch error pub fn parameter_mismatch>(expected: S, found: S) -> Self { Self::ParameterMismatch { expected: expected.into(), found: found.into(), } } /// Create an architecture incompatibility error pub fn architecture_incompatible>(model1: S, model2: S) -> Self { Self::ArchitectureIncompatible { model1: model1.into(), model2: model2.into(), } } /// Create an algorithm error pub fn algorithm>(algorithm: S, reason: S) -> Self { Self::AlgorithmError { algorithm: algorithm.into(), reason: reason.into(), } } /// Create an expert selection error pub fn expert_selection>(reason: S) -> Self { Self::ExpertSelectionError { reason: reason.into(), } } /// Create a conflict resolution error pub fn conflict_resolution(conflicts: usize) -> Self { Self::ConflictResolutionError { conflicts } } /// Create a validation error pub fn validation(checks: Vec) -> Self { Self::ValidationError { checks } } /// Create an evaluation error pub fn evaluation>(metric: S) -> Self { Self::EvaluationError { metric: metric.into(), } } /// Create a configuration error pub fn config>(field: S, message: S) -> Self { Self::ConfigError { field: field.into(), message: message.into(), } } /// Create a memory error pub fn memory(size_mb: usize) -> Self { Self::MemoryError { size_mb } } /// Create a GPU error pub fn gpu>(operation: S) -> Self { Self::GpuError { operation: operation.into(), } } /// Create a numerical error pub fn numerical>(operation: S) -> Self { Self::NumericalError { operation: operation.into(), } } /// Create an I/O error pub fn io>(path: S, source: std::io::Error) -> Self { Self::IoError { path: path.into(), source, } } /// Create a timeout error pub fn timeout(timeout_ms: u64) -> Self { Self::TimeoutError { timeout_ms } } /// Create a resource exhaustion error pub fn resource_exhausted>(resource: S) -> Self { Self::ResourceExhausted { resource: resource.into(), } } /// Create an unsupported format error pub fn unsupported_format>(format: S) -> Self { Self::UnsupportedFormat { format: format.into(), } } /// Create a not implemented error pub fn not_implemented>(feature: S) -> Self { Self::NotImplemented { feature: feature.into(), } } /// Create an internal error pub fn internal>(message: S) -> Self { Self::Internal { message: message.into(), } } /// Check if this error is recoverable pub fn is_recoverable(&self) -> bool { match self { Self::TimeoutError { .. } => true, Self::MemoryError { .. } => true, Self::GpuError { .. } => true, Self::ThreadPoolError(_) => true, Self::ResourceExhausted { .. } => true, _ => false, } } /// Get the error category pub fn category(&self) -> ErrorCategory { match self { Self::ModelLoadError { .. } => ErrorCategory::Loading, Self::CompatibilityError { .. } => ErrorCategory::Compatibility, Self::ParameterMismatch { .. } => ErrorCategory::Compatibility, Self::ArchitectureIncompatible { .. } => ErrorCategory::Compatibility, Self::AlgorithmError { .. } => ErrorCategory::Algorithm, Self::ExpertSelectionError { .. } => ErrorCategory::ExpertSelection, Self::ConflictResolutionError { .. } => ErrorCategory::ConflictResolution, Self::ValidationError { .. } => ErrorCategory::Validation, Self::EvaluationError { .. } => ErrorCategory::Evaluation, Self::ConfigError { .. } => ErrorCategory::Configuration, Self::MemoryError { .. } => ErrorCategory::Resource, Self::GpuError { .. } => ErrorCategory::Resource, Self::NumericalError { .. } => ErrorCategory::Numerical, Self::IoError { .. } => ErrorCategory::IO, Self::SerializationError(_) => ErrorCategory::Serialization, Self::JsonError(_) => ErrorCategory::Serialization, Self::TomlError(_) => ErrorCategory::Serialization, Self::AsyncError(_) => ErrorCategory::Runtime, Self::ThreadPoolError(_) => ErrorCategory::Runtime, Self::TimeoutError { .. } => ErrorCategory::Runtime, Self::ResourceExhausted { .. } => ErrorCategory::Resource, Self::UnsupportedFormat { .. } => ErrorCategory::Format, Self::NotImplemented { .. } => ErrorCategory::NotImplemented, Self::Internal { .. } => ErrorCategory::Internal, } } } /// Error categories for classification and handling #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum ErrorCategory { Loading, Compatibility, Algorithm, ExpertSelection, ConflictResolution, Validation, Evaluation, Configuration, Resource, Numerical, IO, Serialization, Runtime, Format, NotImplemented, Internal, } impl ErrorCategory { /// Get a human-readable description of the error category pub fn description(&self) -> &'static str { match self { Self::Loading => "Model loading and parsing errors", Self::Compatibility => "Model compatibility and architecture mismatches", Self::Algorithm => "Merge algorithm execution errors", Self::ExpertSelection => "Expert selection and routing errors", Self::ConflictResolution => "Parameter conflict resolution errors", Self::Validation => "Model and parameter validation errors", Self::Evaluation => "Performance evaluation and metric computation errors", Self::Configuration => "Configuration parsing and validation errors", Self::Resource => "Memory, GPU, and other resource errors", Self::Numerical => "Numerical stability and computation errors", Self::IO => "File system and network I/O errors", Self::Serialization => "Data serialization and deserialization errors", Self::Runtime => "Async runtime and thread pool errors", Self::Format => "Unsupported or invalid format errors", Self::NotImplemented => "Features not yet implemented", Self::Internal => "Internal library errors", } } /// Check if errors in this category are typically user-fixable pub fn is_user_fixable(&self) -> bool { match self { Self::Loading => true, Self::Compatibility => true, Self::Configuration => true, Self::IO => true, Self::Format => true, _ => false, } } } #[cfg(test)] mod tests { use super::*; #[test] fn test_error_creation() { let err = MergeError::model_load("Test error"); assert!(matches!(err, MergeError::ModelLoadError { .. })); } #[test] fn test_error_categories() { let err = MergeError::compatibility("Test"); assert_eq!(err.category(), ErrorCategory::Compatibility); assert!(err.category().is_user_fixable()); } #[test] fn test_recoverable_errors() { let timeout_err = MergeError::timeout(1000); assert!(timeout_err.is_recoverable()); let internal_err = MergeError::internal("Test"); assert!(!internal_err.is_recoverable()); } #[test] fn test_error_display() { let err = MergeError::parameter_mismatch("expected", "found"); let display = format!("{}", err); assert!(display.contains("expected")); assert!(display.contains("found")); } }