ricecoder_hooks/error.rs
1//! Error types for the hooks system
2//!
3//! This module defines comprehensive error types for the hooks system with clear
4//! error messages and context. All errors use the `thiserror` crate for ergonomic
5//! error handling.
6//!
7//! # Error Handling Patterns
8//!
9//! The hooks system uses explicit error types to enable proper error recovery:
10//!
11//! 1. **Hook Execution Errors**: When a hook fails to execute, the error is logged
12//! but other hooks continue executing (hook isolation).
13//!
14//! 2. **Configuration Errors**: Invalid configuration is rejected with clear messages
15//! indicating what's wrong and how to fix it.
16//!
17//! 3. **Timeout Errors**: Long-running hooks are terminated gracefully with a timeout
18//! error indicating how long the hook ran.
19//!
20//! 4. **Storage Errors**: Configuration loading failures are reported with context
21//! about which configuration file failed and why.
22//!
23//! # Examples
24//!
25//! Handling hook execution errors:
26//!
27//! ```ignore
28//! match executor.execute_hook(&hook, &context) {
29//! Ok(result) => println!("Hook executed: {:?}", result),
30//! Err(HooksError::Timeout(ms)) => eprintln!("Hook timed out after {}ms", ms),
31//! Err(HooksError::ExecutionFailed(msg)) => eprintln!("Hook failed: {}", msg),
32//! Err(e) => eprintln!("Error: {}", e),
33//! }
34//! ```
35
36use thiserror::Error;
37
38/// Errors that can occur in the hooks system
39///
40/// This enum provides comprehensive error types for all operations in the hooks system.
41/// Each variant includes context about what went wrong and how to recover.
42#[derive(Debug, Error)]
43pub enum HooksError {
44 /// Hook not found in the registry
45 ///
46 /// This error occurs when trying to access a hook that doesn't exist.
47 /// The string contains the hook ID that was not found.
48 #[error("Hook not found: {0}")]
49 HookNotFound(String),
50
51 /// Invalid hook configuration
52 ///
53 /// This error occurs when hook configuration is invalid or malformed.
54 /// The string contains details about what's wrong with the configuration.
55 /// Common causes:
56 /// - Missing required fields (event, action)
57 /// - Invalid action type
58 /// - Malformed YAML syntax
59 #[error("Invalid hook configuration: {0}")]
60 InvalidConfiguration(String),
61
62 /// Hook execution failed
63 ///
64 /// This error occurs when a hook action fails to execute.
65 /// The string contains details about what went wrong.
66 /// Note: Hook failures don't affect other hooks (hook isolation).
67 #[error("Hook execution failed: {0}")]
68 ExecutionFailed(String),
69
70 /// Hook execution timed out
71 ///
72 /// This error occurs when a hook takes longer than the configured timeout.
73 /// The u64 contains the timeout duration in milliseconds.
74 /// Recovery: Increase timeout or optimize the hook action.
75 #[error("Hook execution timed out after {0}ms")]
76 Timeout(u64),
77
78 /// Hook is disabled
79 ///
80 /// This error occurs when trying to execute a disabled hook.
81 /// The string contains the hook ID.
82 /// Recovery: Enable the hook using `enable_hook()`.
83 #[error("Hook is disabled: {0}")]
84 HookDisabled(String),
85
86 /// Storage or registry error
87 ///
88 /// This error occurs when there's a problem with hook storage or registry operations.
89 /// The string contains details about what went wrong.
90 /// Common causes:
91 /// - Lock poisoning (concurrent access issue)
92 /// - File system errors
93 /// - Configuration file not found
94 #[error("Storage error: {0}")]
95 StorageError(String),
96
97 /// Configuration validation error
98 ///
99 /// This error occurs when configuration validation fails.
100 /// The string contains details about what validation failed.
101 /// Common causes:
102 /// - Missing required fields
103 /// - Invalid field values
104 /// - Schema validation failure
105 #[error("Configuration validation error: {0}")]
106 ValidationError(String),
107
108 /// Variable substitution error
109 ///
110 /// This error occurs when variable substitution in hook parameters fails.
111 /// The string contains details about what variable is missing or invalid.
112 /// Common causes:
113 /// - Missing variable in event context
114 /// - Invalid variable syntax
115 /// - Type mismatch in substitution
116 #[error("Variable substitution error: {0}")]
117 SubstitutionError(String),
118
119 /// Condition evaluation error
120 ///
121 /// This error occurs when evaluating a hook condition fails.
122 /// The string contains details about what went wrong.
123 /// Common causes:
124 /// - Invalid condition expression
125 /// - Missing context variables
126 /// - Type mismatch in condition
127 #[error("Condition evaluation error: {0}")]
128 ConditionError(String),
129
130 /// Serialization error
131 ///
132 /// This error occurs when serializing or deserializing configuration.
133 /// Wraps `serde_yaml::Error` for YAML parsing failures.
134 #[error("Serialization error: {0}")]
135 SerializationError(#[from] serde_yaml::Error),
136
137 /// IO error
138 ///
139 /// This error occurs when reading or writing files.
140 /// Wraps `std::io::Error` for file system operations.
141 #[error("IO error: {0}")]
142 IoError(#[from] std::io::Error),
143
144 /// JSON error
145 ///
146 /// This error occurs when working with JSON data.
147 /// Wraps `serde_json::Error` for JSON parsing failures.
148 #[error("JSON error: {0}")]
149 JsonError(#[from] serde_json::Error),
150}
151
152/// Result type for hooks operations
153///
154/// This is the standard result type used throughout the hooks system.
155/// All public APIs return `Result<T>` where `T` is the success type.
156///
157/// # Examples
158///
159/// ```ignore
160/// fn register_hook(&mut self, hook: Hook) -> Result<String> {
161/// // ... implementation ...
162/// Ok(hook_id)
163/// }
164/// ```
165pub type Result<T> = std::result::Result<T, HooksError>;