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}