dmsc/core/
error.rs

1//! Copyright © 2025-2026 Wenze Wei. All Rights Reserved.
2//!
3//! This file is part of DMSC.
4//! The DMSC project belongs to the Dunimd Team.
5//!
6//! Licensed under the Apache License, Version 2.0 (the "License");
7//! You may not use this file except in compliance with the License.
8//! You may obtain a copy of the License at
9//!
10//!     http://www.apache.org/licenses/LICENSE-2.0
11//!
12//! Unless required by applicable law or agreed to in writing, software
13//! distributed under the License is distributed on an "AS IS" BASIS,
14//! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15//! See the License for the specific language governing permissions and
16//! limitations under the License.
17
18#![allow(non_snake_case)]
19
20//! # Error Handling
21//! 
22//! This module provides the core error handling types for DMSC, including the `DMSCError` enum
23//! and `DMSCResult` type alias. It defines a comprehensive set of error variants for different
24//! error scenarios encountered in the DMSC library.
25//! 
26//! ## Key Components
27//! 
28//! - **DMSCError**: Enum representing all possible errors in DMSC
29//! - **DMSCResult**: Type alias for `Result<T, DMSCError>` used throughout the library
30//! 
31//! ## Design Principles
32//! 
33//! 1. **Comprehensive Coverage**: Covers all major error categories encountered in DMSC
34//! 2. **Type Safety**: Each error variant provides specific context about the error
35//! 3. **Easy Conversion**: Implements `From` traits for common external error types
36//! 4. **Human-Readable**: Provides clear, descriptive error messages
37//! 5. **Standard Compliance**: Implements `std::error::Error` and `std::fmt::Display`
38//! 
39//! ## Usage
40//! 
41//! ```rust
42//! use dmsc::prelude::*;
43//! 
44//! fn example_function() -> DMSCResult<()> {
45//!     // Return a custom error
46//!     Err(DMSCError::Other("An error occurred"))
47//! }
48//! 
49//! #[tokio::main]
50//! async fn main() -> DMSCResult<()> {
51//!     match example_function() {
52//!         Ok(_) => println!("Success"),
53//!         Err(err) => {
54//!             println!("Error: {}", err);
55//!             Err(err)
56//!         }
57//!     }
58//! }
59//! ```
60
61#[cfg(feature = "pyo3")]
62use pyo3::types::PyTracebackMethods;
63
64/// Core error type for DMSC. Represents all possible errors that can occur in the library.
65/// 
66/// This enum provides a comprehensive set of error variants, each tailored to a specific
67/// error scenario encountered in DMSC. It includes variants for I/O errors, serialization errors,
68/// configuration errors, module errors, and more.
69#[cfg_attr(feature = "pyo3", pyo3::prelude::pyclass)]
70#[derive(Debug, Clone, PartialEq, Eq, Hash)]
71pub enum DMSCError {
72    /// I/O operation failed. Contains a descriptive error message.
73    Io(String),
74    /// Serialization or deserialization failed. Contains a descriptive error message.
75    Serde(String),
76    /// Configuration error. Contains a descriptive error message.
77    Config(String),
78    /// Hook execution error. Contains a descriptive error message.
79    Hook(String),
80    /// Prometheus metrics error. Contains a descriptive error message.
81    Prometheus(String),
82    /// Service mesh error. Contains a descriptive error message.
83    ServiceMesh(String),
84    /// Invalid state error. Indicates an operation was attempted in an invalid state.
85    InvalidState(String),
86    /// Invalid input error. Indicates that provided input data is not valid.
87    InvalidInput(String),
88    /// Security violation error. Indicates a security policy or rule was violated.
89    SecurityViolation(String),
90    /// Device not found. Contains the device ID that was not found.
91    DeviceNotFound { device_id: String },
92    /// Device allocation failed. Contains the device ID and reason for failure.
93    DeviceAllocationFailed { device_id: String, reason: String },
94    /// Allocation not found. Contains the allocation ID that was not found.
95    AllocationNotFound { allocation_id: String },
96    /// Module not found. Contains the module name that was not found.
97    ModuleNotFound { module_name: String },
98    /// Module initialization failed. Contains the module name and reason for failure.
99    ModuleInitFailed { module_name: String, reason: String },
100    /// Module start failed. Contains the module name and reason for failure.
101    ModuleStartFailed { module_name: String, reason: String },
102    /// Module shutdown failed. Contains the module name and reason for failure.
103    ModuleShutdownFailed { module_name: String, reason: String },
104    /// Circular dependency detected. Contains the list of modules involved in the cycle.
105    CircularDependency { modules: Vec<String> },
106    /// Missing dependency. Contains the module name and the missing dependency.
107    MissingDependency { module_name: String, dependency: String },
108    /// Other error. Contains a descriptive error message for unclassified errors.
109    Other(String),
110    /// External error. Contains a descriptive error message for external service errors.
111    ExternalError(String),
112    /// Pool error. Contains a descriptive error message for connection pool errors.
113    PoolError(String),
114    /// Device error. Contains a descriptive error message for device-related errors.
115    DeviceError(String),
116    /// Redis error. Contains a descriptive error message for Redis operations.
117    RedisError(String),
118    /// HTTP client error. Contains a descriptive error message for HTTP requests.
119    HttpClientError(String),
120    /// TOML parsing error. Contains a descriptive error message for TOML parsing.
121    TomlError(String),
122    /// YAML parsing error. Contains a descriptive error message for YAML parsing.
123    YamlError(String),
124    /// Queue error. Contains a descriptive error message for queue operations.
125    Queue(String),
126    /// Frame error. Contains a descriptive error message for frame parsing/building errors.
127    FrameError(String),
128    /// Database error. Contains a descriptive error message for database operations.
129    Database(String),
130}
131
132/// Result type alias for DMSC operations. Used throughout the library.
133/// 
134/// This type alias simplifies error handling by providing a consistent result type
135/// for all DMSC operations. It wraps the standard `Result` type with `DMSCError` as the error type.
136pub type DMSCResult<T> = Result<T, DMSCError>;
137
138/// Implements Display trait for human-readable error messages.
139/// 
140/// Each error variant is formatted with a clear, descriptive prefix indicating
141/// the error category, followed by the specific error details. This enables
142/// developers to quickly identify the source and nature of errors during
143/// development and debugging.
144impl std::fmt::Display for DMSCError {
145    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
146        match self {
147            DMSCError::Io(err) => write!(f, "IO error: {err}"),
148            DMSCError::Serde(err) => write!(f, "Serialization error: {err}"),
149            DMSCError::Config(msg) => write!(f, "Configuration error: {msg}"),
150            DMSCError::Hook(msg) => write!(f, "Hook error: {msg}"),
151            DMSCError::Prometheus(err) => write!(f, "Prometheus error: {err}"),
152            DMSCError::ServiceMesh(err) => write!(f, "Service mesh error: {err}"),
153            DMSCError::InvalidState(msg) => write!(f, "Invalid state: {msg}"),
154            DMSCError::InvalidInput(msg) => write!(f, "Invalid input: {msg}"),
155            DMSCError::SecurityViolation(msg) => write!(f, "Security violation: {msg}"),
156            DMSCError::DeviceNotFound { device_id } => write!(f, "Device not found: {device_id}"),
157            DMSCError::DeviceAllocationFailed { device_id, reason } => {
158                write!(f, "Device allocation failed for {device_id}: {reason}")
159            }
160            DMSCError::AllocationNotFound { allocation_id } => {
161                write!(f, "Allocation not found: {allocation_id}")
162            }
163            DMSCError::ModuleNotFound { module_name } => {
164                write!(f, "Module not found: {module_name}")
165            }
166            DMSCError::ModuleInitFailed { module_name, reason } => {
167                write!(f, "Module initialization failed for {module_name}: {reason}")
168            }
169            DMSCError::ModuleStartFailed { module_name, reason } => {
170                write!(f, "Module start failed for {module_name}: {reason}")
171            }
172            DMSCError::ModuleShutdownFailed { module_name, reason } => {
173                write!(f, "Module shutdown failed for {module_name}: {reason}")
174            }
175            DMSCError::CircularDependency { modules } => {
176                write!(f, "Circular dependency detected: {}", modules.join(" -> "))
177            }
178            DMSCError::MissingDependency { module_name, dependency } => {
179                write!(f, "Module {module_name} depends on missing module: {dependency}")
180            }
181            DMSCError::Other(msg) => write!(f, "{msg}"),
182            DMSCError::ExternalError(msg) => write!(f, "External error: {msg}"),
183            DMSCError::PoolError(msg) => write!(f, "Pool error: {msg}"),
184            DMSCError::DeviceError(msg) => write!(f, "Device error: {msg}"),
185            DMSCError::RedisError(msg) => write!(f, "Redis error: {msg}"),
186            DMSCError::HttpClientError(msg) => write!(f, "HTTP client error: {msg}"),
187            DMSCError::TomlError(msg) => write!(f, "TOML error: {msg}"),
188            DMSCError::YamlError(msg) => write!(f, "YAML error: {msg}"),
189            DMSCError::Queue(msg) => write!(f, "Queue error: {msg}"),
190            DMSCError::FrameError(msg) => write!(f, "Frame error: {msg}"),
191            DMSCError::Database(msg) => write!(f, "Database error: {msg}"),
192        }
193    }
194}
195
196impl std::error::Error for DMSCError {}
197
198/// Enables automatic conversion from standard I/O errors to DMSC errors.
199/// This implementation wraps std::io::Error instances into DMSCError::Io variants,
200/// allowing seamless error propagation when working with file operations, network I/O,
201/// and other standard I/O operations.
202impl From<std::io::Error> for DMSCError {
203    fn from(error: std::io::Error) -> Self {
204        DMSCError::Io(format!("I/O operation failed: {}", error))
205    }
206}
207
208/// Enhanced error formatting with suggestions.
209/// Provides consistent error messages with actionable suggestions for resolution.
210pub struct DMSCErrorFormatter<'a> {
211    error: &'a DMSCError,
212}
213
214impl<'a> DMSCErrorFormatter<'a> {
215    /// Creates a new error formatter for the given error.
216    pub fn new(error: &'a DMSCError) -> Self {
217        Self { error }
218    }
219
220    /// Returns the formatted error message with suggestion.
221    pub fn format(&self) -> String {
222        let base_message = self.error.to_string();
223        let suggestion = self.get_suggestion();
224
225        match suggestion {
226            Some(s) => format!("{}\n💡 Suggestion: {}", base_message, s),
227            None => base_message,
228        }
229    }
230
231    /// Returns an actionable suggestion for the error.
232    fn get_suggestion(&self) -> Option<&'static str> {
233        match self.error {
234            DMSCError::Io(_) => Some("Check file permissions and disk space"),
235            DMSCError::Serde(_) => Some("Verify data format matches expected schema"),
236            DMSCError::Config(_) => Some("Review configuration file syntax and required fields"),
237            DMSCError::Hook(_) => Some("Check hook implementation for errors and ensure proper registration"),
238            DMSCError::Prometheus(_) => Some("Verify Prometheus server is running and metrics endpoint is accessible"),
239            DMSCError::ServiceMesh(_) => Some("Check service mesh configuration and network connectivity"),
240            DMSCError::InvalidState(_) => Some("Ensure module is in correct state before performing operation"),
241            DMSCError::InvalidInput(_) => Some("Validate input data against expected format and constraints"),
242            DMSCError::SecurityViolation(_) => Some("Review security policies and access permissions"),
243            DMSCError::DeviceNotFound { .. } => Some("Verify device ID exists and is properly registered"),
244            DMSCError::DeviceAllocationFailed { .. } => Some("Check device availability and allocation constraints"),
245            DMSCError::AllocationNotFound { .. } => Some("Verify allocation ID is correct and hasn't expired"),
246            DMSCError::ModuleNotFound { .. } => Some("Ensure module is registered and feature flag is enabled"),
247            DMSCError::ModuleInitFailed { .. } => Some("Check module dependencies and initialization parameters"),
248            DMSCError::ModuleStartFailed { .. } => Some("Review module start sequence and resource availability"),
249            DMSCError::ModuleShutdownFailed { .. } => Some("Ensure no active connections before shutdown"),
250            DMSCError::CircularDependency { .. } => Some("Restructure module dependencies to eliminate cycles"),
251            DMSCError::MissingDependency { .. } => Some("Add required module to application configuration"),
252            DMSCError::Other(_) => None,
253            DMSCError::ExternalError(_) => Some("Check external service status and credentials"),
254            DMSCError::PoolError(_) => Some("Verify connection pool configuration and database availability"),
255            DMSCError::DeviceError(_) => Some("Check device connection and configuration"),
256            DMSCError::RedisError(_) => Some("Verify Redis server is running and connection parameters are correct"),
257            DMSCError::HttpClientError(_) => Some("Check network connectivity and target server availability"),
258            DMSCError::TomlError(_) => Some("Validate TOML syntax and required sections"),
259            DMSCError::YamlError(_) => Some("Validate YAML syntax and indentation"),
260            DMSCError::Queue(_) => Some("Check message queue service status and queue configuration"),
261            DMSCError::FrameError(_) => Some("Check frame format and protocol compatibility"),
262            DMSCError::Database(_) => Some("Verify database connection and query syntax"),
263        }
264    }
265}
266
267/// Formats an error with actionable suggestion.
268/// This helper function provides enhanced error messages that include
269/// suggestions for resolving the issue.
270#[inline]
271pub fn format_error(error: &DMSCError) -> String {
272    DMSCErrorFormatter::new(error).format()
273}
274
275/// Logs an error with enhanced formatting.
276/// This helper function logs the error with its suggestion for debugging.
277#[inline]
278pub fn log_error(error: &DMSCError) {
279    log::error!("{}", format_error(error));
280}
281
282/// Enables automatic conversion from JSON serialization/deserialization errors.
283/// This implementation wraps serde_json::Error instances into DMSCError::Serde variants,
284/// providing consistent error handling for JSON parsing and generation operations.
285impl From<serde_json::Error> for DMSCError {
286    fn from(error: serde_json::Error) -> Self {
287        DMSCError::Serde(error.to_string())
288    }
289}
290
291/// Enables automatic conversion from Prometheus metrics errors to DMSC errors.
292/// This implementation is conditionally compiled with the "observability" feature.
293/// Prometheus errors are wrapped into DMSCError::Prometheus variants.
294#[cfg(feature = "observability")]
295impl From<prometheus::Error> for DMSCError {
296    fn from(error: prometheus::Error) -> Self {
297        DMSCError::Prometheus(error.to_string())
298    }
299}
300
301/// Enables automatic conversion from Redis client errors to DMSC errors.
302/// This implementation is conditionally compiled with the "redis" feature.
303/// Redis errors are wrapped into DMSCError::RedisError variants, providing
304/// consistent error handling for Redis connection and operation failures.
305#[cfg(feature = "redis")]
306impl From<redis::RedisError> for DMSCError {
307    fn from(error: redis::RedisError) -> Self {
308        DMSCError::RedisError(error.to_string())
309    }
310}
311
312/// Enables automatic conversion from HTTP client errors to DMSC errors.
313/// This implementation is conditionally compiled with the "http_client" feature.
314/// HTTP request failures, timeouts, and network errors are wrapped into
315/// DMSCError::HttpClientError variants for consistent error handling.
316#[cfg(feature = "http_client")]
317impl From<reqwest::Error> for DMSCError {
318    fn from(error: reqwest::Error) -> Self {
319        DMSCError::HttpClientError(error.to_string())
320    }
321}
322
323/// Enables automatic conversion from TOML parsing errors to DMSC errors.
324/// This implementation wraps toml::de::Error instances into DMSCError::TomlError variants,
325/// providing consistent error handling for TOML configuration file parsing.
326impl From<toml::de::Error> for DMSCError {
327    fn from(error: toml::de::Error) -> Self {
328        DMSCError::TomlError(error.to_string())
329    }
330}
331
332/// Enables automatic conversion from TOML serialization errors to DMSC errors.
333/// This implementation wraps toml::ser::Error instances into DMSCError::TomlError variants,
334/// providing consistent error handling for TOML configuration generation.
335impl From<toml::ser::Error> for DMSCError {
336    fn from(error: toml::ser::Error) -> Self {
337        DMSCError::TomlError(error.to_string())
338    }
339}
340
341/// Enables automatic conversion from YAML parsing errors to DMSC errors.
342/// This implementation wraps serde_yaml::Error instances into DMSCError::YamlError variants,
343/// providing consistent error handling for YAML configuration file parsing.
344impl From<serde_yaml::Error> for DMSCError {
345    fn from(error: serde_yaml::Error) -> Self {
346        DMSCError::YamlError(error.to_string())
347    }
348}
349
350/// Enables automatic conversion from RabbitMQ client errors to DMSC errors.
351/// This implementation is conditionally compiled with the "rabbitmq" feature.
352/// RabbitMQ connection and channel errors are wrapped into DMSCError::Other variants
353/// with a "RabbitMQ error:" prefix for consistent error categorization.
354#[cfg(feature = "rabbitmq")]
355impl From<lapin::Error> for DMSCError {
356    fn from(error: lapin::Error) -> Self {
357        DMSCError::Other(format!("RabbitMQ error: {error}"))
358    }
359}
360
361/// Enables automatic conversion from Kafka client errors to DMSC errors.
362/// This implementation is conditionally compiled with the "kafka" feature on non-Windows platforms.
363/// Kafka producer, consumer, and administration errors are wrapped into DMSCError::Queue variants
364/// for consistent error handling in message queue operations.
365#[cfg(all(feature = "kafka", not(windows)))]
366impl From<rdkafka::error::KafkaError> for DMSCError {
367    fn from(error: rdkafka::error::KafkaError) -> Self {
368        DMSCError::Queue(format!("Kafka error: {}", error))
369    }
370}
371
372/// Stub implementation for Kafka errors on Windows.
373/// This prevents compilation errors on Windows where rdkafka is not available.
374/// The actual Kafka functionality is disabled on Windows via the kafka_stub module.
375#[cfg(all(feature = "kafka", windows))]
376impl From<rdkafka::error::KafkaError> for DMSCError {
377    fn from(error: rdkafka::error::KafkaError) -> Self {
378        DMSCError::Queue(format!("Kafka error: {}", error))
379    }
380}
381
382impl From<tokio::time::error::Elapsed> for DMSCError {
383    fn from(error: tokio::time::error::Elapsed) -> Self {
384        DMSCError::Io(format!("Operation timed out: {}", error))
385    }
386}
387
388impl From<std::str::Utf8Error> for DMSCError {
389    fn from(error: std::str::Utf8Error) -> Self {
390        DMSCError::Serde(format!("UTF-8 conversion error: {}", error))
391    }
392}
393
394impl From<tokio::sync::TryLockError> for DMSCError {
395    fn from(error: tokio::sync::TryLockError) -> Self {
396        DMSCError::InvalidState(format!("Lock acquisition failed: {}", error))
397    }
398}
399
400impl From<super::lock::DMSCLockError> for DMSCError {
401    fn from(error: super::lock::DMSCLockError) -> Self {
402        DMSCError::InvalidState(format!("Lock error: {}", error))
403    }
404}
405
406#[cfg(feature = "pyo3")]
407impl std::convert::From<DMSCError> for pyo3::PyErr {
408    fn from(error: DMSCError) -> Self {
409        pyo3::exceptions::PyRuntimeError::new_err(error.to_string())
410    }
411}
412
413#[cfg(feature = "pyo3")]
414impl std::convert::From<pyo3::PyErr> for DMSCError {
415    fn from(error: pyo3::PyErr) -> Self {
416        let error_info = pyo3::Python::attach(|py| {
417            let traceback = error.traceback(py)
418                .and_then(|tb| tb.format().ok())
419                .unwrap_or_default();
420            let error_type = error.get_type(py).to_string();
421            let error_value = error.value(py).to_string();
422            format!("{}: {}\n{}", error_type, error_value, traceback)
423        });
424        DMSCError::Other(format!("Python error: {}", error_info))
425    }
426}
427
428#[cfg(feature = "pyo3")]
429/// Python bindings for DMSCError.
430///
431/// This implementation provides a Python interface for the DMSCError type, enabling
432/// Python applications to create, inspect, and handle DMSC errors. The bindings expose
433/// factory methods for creating specific error types and predicate methods for checking
434/// error variants at runtime.
435///
436/// ## Python Usage Example
437///
438/// ```python
439/// 
440///
441/// try:
442///     # Some operation that might fail
443///     pass
444/// except Exception as e:
445///     if isinstance(e, dms.DMSCError):
446///         print(f"Error type: {type(e)}")
447///         if e.is_io():
448///             print("I/O error occurred")
449/// ```
450///
451/// ## Available Methods
452///
453/// - **Factory methods**: Create specific error types from Python
454/// - **Inspection methods**: Check the error variant at runtime
455/// - **String representation**: __str__ and __repr__ for display
456#[pyo3::prelude::pymethods]
457impl DMSCError {
458    /// Returns the string representation of the error.
459    ///
460    /// This method implements the Python __str__ protocol, returning a human-readable
461    /// error message that describes the error. The format matches the Display trait
462    /// implementation in Rust, providing consistent output across language boundaries.
463    ///
464    /// Returns:
465    ///     A String containing the formatted error message
466    pub fn __str__(&self) -> String {
467        self.to_string()
468    }
469
470    /// Returns the debug representation of the error.
471    ///
472    /// This method implements the Python __repr__ protocol, returning a detailed
473    /// representation suitable for debugging. Unlike __str__, this format includes
474    /// the specific error variant and all associated data.
475    ///
476    /// Returns:
477    ///     A String containing the debug-formatted error representation
478    pub fn __repr__(&self) -> String {
479        format!("{:?}", self)
480    }
481
482    /// Creates a new DMSCError from a string message.
483    ///
484    /// This factory method creates an Other variant error containing the provided
485    /// message. It serves as a generic error constructor for custom error scenarios
486    /// that don't fit other specific error types.
487    ///
488    /// Arguments:
489    ///     message: The error message describing the failure
490    ///
491    /// Returns:
492    ///     A new DMSCError instance with Other variant
493    #[staticmethod]
494    pub fn from_str(message: &str) -> Self {
495        DMSCError::Other(message.to_string())
496    }
497
498    /// Creates a new IO error.
499    ///
500    /// This factory method creates an Io variant error for I/O operation failures.
501    /// Use this when file operations, network I/O, or other standard I/O operations fail.
502    ///
503    /// Arguments:
504    ///     message: A description of the I/O failure
505    ///
506    /// Returns:
507    ///     A new DMSCError instance with Io variant
508    #[staticmethod]
509    pub fn io(message: &str) -> Self {
510        DMSCError::Io(message.to_string())
511    }
512
513    /// Creates a new serialization error.
514    ///
515    /// This factory method creates a Serde variant error for serialization or
516    /// deserialization failures. Use this for JSON, binary, or other data format
517    /// conversion errors.
518    ///
519    /// Arguments:
520    ///     message: A description of the serialization failure
521    ///
522    /// Returns:
523    ///     A new DMSCError instance with Serde variant
524    #[staticmethod]
525    pub fn serde(message: &str) -> Self {
526        DMSCError::Serde(message.to_string())
527    }
528
529    /// Creates a new configuration error.
530    ///
531    /// This factory method creates a Config variant error for configuration-related
532    /// failures. Use this when configuration files are invalid, missing, or contain
533    /// unsupported values.
534    ///
535    /// Arguments:
536    ///     message: A description of the configuration error
537    ///
538    /// Returns:
539    ///     A new DMSCError instance with Config variant
540    #[staticmethod]
541    pub fn config(message: &str) -> Self {
542        DMSCError::Config(message.to_string())
543    }
544
545    /// Creates a new hook execution error.
546    ///
547    /// This factory method creates a Hook variant error for hook callback failures.
548    /// Use this when a registered hook function fails to execute properly.
549    ///
550    /// Arguments:
551    ///     message: A description of the hook execution failure
552    ///
553    /// Returns:
554    ///     A new DMSCError instance with Hook variant
555    #[staticmethod]
556    pub fn hook(message: &str) -> Self {
557        DMSCError::Hook(message.to_string())
558    }
559
560    /// Checks if this error is an IO error.
561    ///
562    /// This predicate method returns true if the error is an Io variant.
563    /// Use this for conditional error handling based on error type.
564    ///
565    /// Returns:
566    ///     true if the error is an Io variant, false otherwise
567    pub fn is_io(&self) -> bool {
568        matches!(self, DMSCError::Io(_))
569    }
570
571    /// Checks if this error is a serialization error.
572    ///
573    /// This predicate method returns true if the error is a Serde variant.
574    /// Use this for conditional error handling based on error type.
575    ///
576    /// Returns:
577    ///     true if the error is a Serde variant, false otherwise
578    pub fn is_serde(&self) -> bool {
579        matches!(self, DMSCError::Serde(_))
580    }
581
582    /// Checks if this error is a configuration error.
583    ///
584    /// This predicate method returns true if the error is a Config variant.
585    /// Use this for conditional error handling based on error type.
586    ///
587    /// Returns:
588    ///     true if the error is a Config variant, false otherwise
589    pub fn is_config(&self) -> bool {
590        matches!(self, DMSCError::Config(_))
591    }
592
593    /// Checks if this error is a hook error.
594    ///
595    /// This predicate method returns true if the error is a Hook variant.
596    /// Use this for conditional error handling based on error type.
597    ///
598    /// Returns:
599    ///     true if the error is a Hook variant, false otherwise
600    pub fn is_hook(&self) -> bool {
601        matches!(self, DMSCError::Hook(_))
602    }
603
604    /// Checks if this error is a Prometheus metrics error.
605    ///
606    /// This predicate method returns true if the error is a Prometheus variant.
607    /// This method is only available when the "observability" feature is enabled.
608    ///
609    /// Returns:
610    ///     true if the error is a Prometheus variant, false otherwise
611    pub fn is_prometheus(&self) -> bool {
612        matches!(self, DMSCError::Prometheus(_))
613    }
614
615    /// Checks if this error is a service mesh error.
616    ///
617    /// This predicate method returns true if the error is a ServiceMesh variant.
618    /// Use this for conditional error handling related to service mesh operations.
619    ///
620    /// Returns:
621    ///     true if the error is a ServiceMesh variant, false otherwise
622    pub fn is_service_mesh(&self) -> bool {
623        matches!(self, DMSCError::ServiceMesh(_))
624    }
625
626    /// Checks if this error is an invalid state error.
627    ///
628    /// This predicate method returns true if the error is an InvalidState variant.
629    /// Use this when an operation was attempted in an invalid program state.
630    ///
631    /// Returns:
632    ///     true if the error is an InvalidState variant, false otherwise
633    pub fn is_invalid_state(&self) -> bool {
634        matches!(self, DMSCError::InvalidState(_))
635    }
636
637    /// Checks if this error is an invalid input error.
638    ///
639    /// This predicate method returns true if the error is an InvalidInput variant.
640    /// Use this when provided input data fails validation checks.
641    ///
642    /// Returns:
643    ///     true if the error is an InvalidInput variant, false otherwise
644    pub fn is_invalid_input(&self) -> bool {
645        matches!(self, DMSCError::InvalidInput(_))
646    }
647
648    /// Checks if this error is a security violation error.
649    ///
650    /// This predicate method returns true if the error is a SecurityViolation variant.
651    /// Use this when a security policy or rule has been violated.
652    ///
653    /// Returns:
654    ///     true if the error is a SecurityViolation variant, false otherwise
655    pub fn is_security_violation(&self) -> bool {
656        matches!(self, DMSCError::SecurityViolation(_))
657    }
658
659    /// Checks if this error is a device not found error.
660    ///
661    /// This predicate method returns true if the error is a DeviceNotFound variant.
662    /// Use this when a requested device identifier does not exist.
663    ///
664    /// Returns:
665    ///     true if the error is a DeviceNotFound variant, false otherwise
666    pub fn is_device_not_found(&self) -> bool {
667        matches!(self, DMSCError::DeviceNotFound { .. })
668    }
669
670    /// Checks if this error is a device allocation failed error.
671    ///
672    /// This predicate method returns true if the error is a DeviceAllocationFailed variant.
673    /// Use this when a device cannot be allocated for use.
674    ///
675    /// Returns:
676    ///     true if the error is a DeviceAllocationFailed variant, false otherwise
677    pub fn is_device_allocation_failed(&self) -> bool {
678        matches!(self, DMSCError::DeviceAllocationFailed { .. })
679    }
680
681    /// Checks if this error is an allocation not found error.
682    ///
683    /// This predicate method returns true if the error is an AllocationNotFound variant.
684    /// Use this when a requested allocation identifier does not exist.
685    ///
686    /// Returns:
687    ///     true if the error is an AllocationNotFound variant, false otherwise
688    pub fn is_allocation_not_found(&self) -> bool {
689        matches!(self, DMSCError::AllocationNotFound { .. })
690    }
691
692    /// Checks if this error is a module not found error.
693    ///
694    /// This predicate method returns true if the error is a ModuleNotFound variant.
695    /// Use this when a requested module does not exist in the system.
696    ///
697    /// Returns:
698    ///     true if the error is a ModuleNotFound variant, false otherwise
699    pub fn is_module_not_found(&self) -> bool {
700        matches!(self, DMSCError::ModuleNotFound { .. })
701    }
702
703    /// Checks if this error is a module initialization failed error.
704    ///
705    /// This predicate method returns true if the error is a ModuleInitFailed variant.
706    /// Use this when a module fails to initialize properly.
707    ///
708    /// Returns:
709    ///     true if the error is a ModuleInitFailed variant, false otherwise
710    pub fn is_module_init_failed(&self) -> bool {
711        matches!(self, DMSCError::ModuleInitFailed { .. })
712    }
713
714    /// Checks if this error is a module start failed error.
715    ///
716    /// This predicate method returns true if the error is a ModuleStartFailed variant.
717    /// Use this when a module fails to start after successful initialization.
718    ///
719    /// Returns:
720    ///     true if the error is a ModuleStartFailed variant, false otherwise
721    pub fn is_module_start_failed(&self) -> bool {
722        matches!(self, DMSCError::ModuleStartFailed { .. })
723    }
724
725    /// Checks if this error is a module shutdown failed error.
726    ///
727    /// This predicate method returns true if the error is a ModuleShutdownFailed variant.
728    /// Use this when a module fails to shut down gracefully.
729    ///
730    /// Returns:
731    ///     true if the error is a ModuleShutdownFailed variant, false otherwise
732    pub fn is_module_shutdown_failed(&self) -> bool {
733        matches!(self, DMSCError::ModuleShutdownFailed { .. })
734    }
735
736    /// Checks if this error is a circular dependency error.
737    ///
738    /// This predicate method returns true if the error is a CircularDependency variant.
739    /// Use this when modules have circular import or initialization dependencies.
740    ///
741    /// Returns:
742    ///     true if the error is a CircularDependency variant, false otherwise
743    pub fn is_circular_dependency(&self) -> bool {
744        matches!(self, DMSCError::CircularDependency { .. })
745    }
746
747    /// Checks if this error is a missing dependency error.
748    ///
749    /// This predicate method returns true if the error is a MissingDependency variant.
750    /// Use this when a module depends on another module that is not available.
751    ///
752    /// Returns:
753    ///     true if the error is a MissingDependency variant, false otherwise
754    pub fn is_missing_dependency(&self) -> bool {
755        matches!(self, DMSCError::MissingDependency { .. })
756    }
757
758    /// Checks if this error is a generic other error.
759    ///
760    /// This predicate method returns true if the error is an Other variant.
761    /// Use this as a catch-all check for unclassified errors.
762    ///
763    /// Returns:
764    ///     true if the error is an Other variant, false otherwise
765    pub fn is_other(&self) -> bool {
766        matches!(self, DMSCError::Other(_))
767    }
768
769    /// Checks if this error is an external error.
770    ///
771    /// This predicate method returns true if the error is an ExternalError variant.
772    /// Use this for errors originating from external services or dependencies.
773    ///
774    /// Returns:
775    ///     true if the error is an ExternalError variant, false otherwise
776    pub fn is_external_error(&self) -> bool {
777        matches!(self, DMSCError::ExternalError(_))
778    }
779
780    /// Checks if this error is a connection pool error.
781    ///
782    /// This predicate method returns true if the error is a PoolError variant.
783    /// Use this for errors related to connection pool management.
784    ///
785    /// Returns:
786    ///     true if the error is a PoolError variant, false otherwise
787    pub fn is_pool_error(&self) -> bool {
788        matches!(self, DMSCError::PoolError(_))
789    }
790
791    /// Checks if this error is a device error.
792    ///
793    /// This predicate method returns true if the error is a DeviceError variant.
794    /// Use this for general device-related errors not covered by specific variants.
795    ///
796    /// Returns:
797    ///     true if the error is a DeviceError variant, false otherwise
798    pub fn is_device_error(&self) -> bool {
799        matches!(self, DMSCError::DeviceError(_))
800    }
801
802    /// Checks if this error is a Redis error.
803    ///
804    /// This predicate method returns true if the error is a RedisError variant.
805    /// This method is only available when the "redis" feature is enabled.
806    ///
807    /// Returns:
808    ///     true if the error is a RedisError variant, false otherwise
809    pub fn is_redis_error(&self) -> bool {
810        matches!(self, DMSCError::RedisError(_))
811    }
812
813    /// Checks if this error is an HTTP client error.
814    ///
815    /// This predicate method returns true if the error is an HttpClientError variant.
816    /// This method is only available when the "http_client" feature is enabled.
817    ///
818    /// Returns:
819    ///     true if the error is an HttpClientError variant, false otherwise
820    pub fn is_http_client_error(&self) -> bool {
821        matches!(self, DMSCError::HttpClientError(_))
822    }
823
824    /// Checks if this error is a TOML parsing error.
825    ///
826    /// This predicate method returns true if the error is a TomlError variant.
827    /// Use this for errors related to TOML configuration file parsing.
828    ///
829    /// Returns:
830    ///     true if the error is a TomlError variant, false otherwise
831    pub fn is_toml_error(&self) -> bool {
832        matches!(self, DMSCError::TomlError(_))
833    }
834
835    /// Checks if this error is a YAML parsing error.
836    ///
837    /// This predicate method returns true if the error is a YamlError variant.
838    /// Use this for errors related to YAML configuration file parsing.
839    ///
840    /// Returns:
841    ///     true if the error is a YamlError variant, false otherwise
842    pub fn is_yaml_error(&self) -> bool {
843        matches!(self, DMSCError::YamlError(_))
844    }
845
846    /// Checks if this error is a queue error.
847    ///
848    /// This predicate method returns true if the error is a Queue variant.
849    /// Use this for errors related to message queue operations (RabbitMQ, Kafka).
850    ///
851    /// Returns:
852    ///     true if the error is a Queue variant, false otherwise
853    pub fn is_queue(&self) -> bool {
854        matches!(self, DMSCError::Queue(_))
855    }
856}