tcrm_task/tasks/
error.rs

1use thiserror::Error;
2
3/// Errors that can occur during task configuration and execution
4///
5/// `TaskError` represents all error conditions that can arise when configuring,
6/// validating, or executing tasks. Each variant provides specific context
7/// about the failure to enable proper error handling and debugging.
8///
9/// # Examples
10///
11/// ## Error Handling
12/// ```rust
13/// use tcrm_task::tasks::{config::TaskConfig, error::TaskError};
14///
15/// fn validate_config(config: &TaskConfig) -> Result<(), String> {
16///     match config.validate() {
17///         Ok(()) => Ok(()),
18///         Err(TaskError::InvalidConfiguration(msg)) => {
19///             Err(format!("Configuration error: {}", msg))
20///         }
21///         Err(TaskError::IO(msg)) => {
22///             Err(format!("IO error: {}", msg))
23///         }
24///         Err(other) => {
25///             Err(format!("Other error: {}", other))
26///         }
27///     }
28/// }
29/// ```
30///
31/// ## Pattern Matching on Events
32/// ```rust
33/// use tcrm_task::tasks::{event::TaskEvent, error::TaskError};
34///
35/// fn handle_event(event: TaskEvent) {
36///     match event {
37///         TaskEvent::Error { task_name, error } => {
38///             match error {
39///                 TaskError::IO(msg) => {
40///                     eprintln!("Task '{}' IO error: {}", task_name, msg);
41///                 }
42///                 TaskError::InvalidConfiguration(msg) => {
43///                     eprintln!("Task '{}' config error: {}", task_name, msg);
44///                 }
45///                 TaskError::Channel(msg) => {
46///                     eprintln!("Task '{}' channel error: {}", task_name, msg);
47///                 }
48///                 _ => {
49///                     eprintln!("Task '{}' error: {}", task_name, error);
50///                 }
51///             }
52///         }
53///         _ => {}
54///     }
55/// }
56/// ```
57#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
58#[derive(Error, Debug, Clone, PartialEq)]
59pub enum TaskError {
60    /// Input/Output operation failed
61    ///
62    /// Covers file system operations, process spawning failures,
63    /// and other system-level IO errors.
64    ///
65    /// # Common Causes
66    /// - Command not found in PATH
67    /// - Permission denied when spawning process
68    /// - Working directory doesn't exist or isn't accessible
69    /// - File descriptor or pipe creation failures
70    #[error("IO error: {0}")]
71    IO(String),
72
73    /// Process handle operation failed
74    ///
75    /// Errors related to process management operations like
76    /// getting process ID, waiting for completion, or termination.
77    ///
78    /// # Common Causes
79    /// - Failed to get process ID after spawn
80    /// - Process handle became invalid
81    /// - Termination signal delivery failed
82    #[error("Handle error: {0}")]
83    Handle(String),
84
85    /// Inter-task communication channel error
86    ///
87    /// Failures in the async channel system used for event delivery,
88    /// stdin input, or process coordination.
89    ///
90    /// # Common Causes
91    /// - Event channel closed unexpectedly
92    /// - Stdin channel disconnected
93    /// - Termination signal channel closed
94    /// - Receiver dropped before sender finished
95    #[error("Channel error: {0}")]
96    Channel(String),
97
98    /// Task configuration validation failed
99    ///
100    /// The task configuration contains invalid parameters that
101    /// prevent safe execution. Always check these before starting tasks.
102    ///
103    /// # Common Causes
104    /// - Empty command string
105    /// - Invalid characters in command or arguments
106    /// - Working directory doesn't exist
107    /// - Environment variables with invalid keys
108    /// - Zero or negative timeout values
109    /// - Security validation failures (command injection, etc.)
110    #[error("Invalid configuration: {0}")]
111    InvalidConfiguration(String),
112
113    /// Application-specific or unexpected error
114    ///
115    /// Used for errors that don't fit other categories or
116    /// for wrapping external errors from dependencies.
117    ///
118    /// # Common Causes
119    /// - Custom validation logic failures
120    /// - Wrapped errors from external libraries
121    /// - Unexpected internal state conditions
122    #[error("Custom error: {0}")]
123    Custom(String),
124}