Skip to main content

pollen_types/
error.rs

1//! Error types for Pollen.
2
3use thiserror::Error;
4use crate::{TaskId, InstanceId, NodeId};
5
6/// Result type for Pollen operations.
7pub type Result<T> = std::result::Result<T, PollenError>;
8
9/// Main error type for Pollen operations.
10#[derive(Error, Debug)]
11pub enum PollenError {
12    /// Task not found by ID.
13    #[error("task not found: {0}")]
14    TaskNotFound(TaskId),
15
16    /// Task not found by name.
17    #[error("task not found: {0}")]
18    TaskNameNotFound(String),
19
20    /// Task already exists.
21    #[error("task already exists: {0}")]
22    TaskAlreadyExists(String),
23
24    /// Task instance not found.
25    #[error("task instance not found: {0}")]
26    InstanceNotFound(InstanceId),
27
28    /// Node not found in cluster.
29    #[error("node not found: {0}")]
30    NodeNotFound(NodeId),
31
32    /// Invalid cron expression.
33    #[error("invalid cron expression: {0}")]
34    InvalidCron(String),
35
36    /// Invalid schedule configuration.
37    #[error("invalid schedule: {0}")]
38    InvalidSchedule(String),
39
40    /// Storage error.
41    #[error("storage error: {0}")]
42    Storage(#[from] StorageError),
43
44    /// Transport error.
45    #[error("transport error: {0}")]
46    Transport(#[from] TransportError),
47
48    /// Cluster error.
49    #[error("cluster error: {0}")]
50    Cluster(#[from] ClusterError),
51
52    /// Execution error.
53    #[error("execution error: {0}")]
54    Execution(#[from] ExecutionError),
55
56    /// Serialization error.
57    #[error("serialization error: {0}")]
58    Serialization(String),
59
60    /// Configuration error.
61    #[error("configuration error: {0}")]
62    Config(String),
63
64    /// Operation cancelled.
65    #[error("operation cancelled")]
66    Cancelled,
67
68    /// Timeout.
69    #[error("operation timed out")]
70    Timeout,
71
72    /// Internal error.
73    #[error("internal error: {0}")]
74    Internal(String),
75}
76
77/// Storage-specific errors.
78#[derive(Error, Debug)]
79pub enum StorageError {
80    /// SQLite error.
81    #[error("sqlite error: {0}")]
82    Sqlite(String),
83
84    /// Transaction failed.
85    #[error("transaction failed: {0}")]
86    TransactionFailed(String),
87
88    /// Optimistic lock conflict.
89    #[error("version conflict: expected {expected}, found {found}")]
90    VersionConflict { expected: u64, found: u64 },
91
92    /// IO error.
93    #[error("io error: {0}")]
94    Io(#[from] std::io::Error),
95}
96
97/// Transport-specific errors.
98#[derive(Error, Debug)]
99pub enum TransportError {
100    /// Connection failed.
101    #[error("connection failed to {addr}: {reason}")]
102    ConnectionFailed { addr: String, reason: String },
103
104    /// Connection closed.
105    #[error("connection closed")]
106    ConnectionClosed,
107
108    /// Send failed.
109    #[error("send failed: {0}")]
110    SendFailed(String),
111
112    /// Receive failed.
113    #[error("receive failed: {0}")]
114    ReceiveFailed(String),
115
116    /// TLS error.
117    #[error("tls error: {0}")]
118    Tls(String),
119
120    /// Address parse error.
121    #[error("invalid address: {0}")]
122    InvalidAddress(String),
123}
124
125/// Cluster-specific errors.
126#[derive(Error, Debug)]
127pub enum ClusterError {
128    /// Not a cluster member.
129    #[error("not a cluster member")]
130    NotMember,
131
132    /// Gossip protocol error.
133    #[error("gossip error: {0}")]
134    Gossip(String),
135
136    /// CRDT merge conflict.
137    #[error("crdt merge error: {0}")]
138    CrdtMerge(String),
139
140    /// Node unreachable.
141    #[error("node unreachable: {0}")]
142    NodeUnreachable(NodeId),
143}
144
145/// Execution-specific errors.
146#[derive(Error, Debug)]
147pub enum ExecutionError {
148    /// Handler not found.
149    #[error("handler not found for task: {0}")]
150    HandlerNotFound(TaskId),
151
152    /// Handler panicked.
153    #[error("handler panicked: {0}")]
154    HandlerPanic(String),
155
156    /// Task timeout.
157    #[error("task execution timed out after {0:?}")]
158    Timeout(std::time::Duration),
159
160    /// Maximum retries exceeded.
161    #[error("max retries ({max}) exceeded")]
162    MaxRetriesExceeded { max: u32 },
163
164    /// Claim failed.
165    #[error("failed to claim task instance")]
166    ClaimFailed,
167}
168
169impl From<bincode::Error> for PollenError {
170    fn from(err: bincode::Error) -> Self {
171        PollenError::Serialization(err.to_string())
172    }
173}
174
175#[cfg(test)]
176mod tests {
177    use super::*;
178
179    #[test]
180    fn test_error_display() {
181        let err = PollenError::TaskNotFound(TaskId::new());
182        assert!(err.to_string().contains("task not found"));
183    }
184}