1use thiserror::Error;
4use crate::{TaskId, InstanceId, NodeId};
5
6pub type Result<T> = std::result::Result<T, PollenError>;
8
9#[derive(Error, Debug)]
11pub enum PollenError {
12 #[error("task not found: {0}")]
14 TaskNotFound(TaskId),
15
16 #[error("task not found: {0}")]
18 TaskNameNotFound(String),
19
20 #[error("task already exists: {0}")]
22 TaskAlreadyExists(String),
23
24 #[error("task instance not found: {0}")]
26 InstanceNotFound(InstanceId),
27
28 #[error("node not found: {0}")]
30 NodeNotFound(NodeId),
31
32 #[error("invalid cron expression: {0}")]
34 InvalidCron(String),
35
36 #[error("invalid schedule: {0}")]
38 InvalidSchedule(String),
39
40 #[error("storage error: {0}")]
42 Storage(#[from] StorageError),
43
44 #[error("transport error: {0}")]
46 Transport(#[from] TransportError),
47
48 #[error("cluster error: {0}")]
50 Cluster(#[from] ClusterError),
51
52 #[error("execution error: {0}")]
54 Execution(#[from] ExecutionError),
55
56 #[error("serialization error: {0}")]
58 Serialization(String),
59
60 #[error("configuration error: {0}")]
62 Config(String),
63
64 #[error("operation cancelled")]
66 Cancelled,
67
68 #[error("operation timed out")]
70 Timeout,
71
72 #[error("internal error: {0}")]
74 Internal(String),
75}
76
77#[derive(Error, Debug)]
79pub enum StorageError {
80 #[error("sqlite error: {0}")]
82 Sqlite(String),
83
84 #[error("transaction failed: {0}")]
86 TransactionFailed(String),
87
88 #[error("version conflict: expected {expected}, found {found}")]
90 VersionConflict { expected: u64, found: u64 },
91
92 #[error("io error: {0}")]
94 Io(#[from] std::io::Error),
95}
96
97#[derive(Error, Debug)]
99pub enum TransportError {
100 #[error("connection failed to {addr}: {reason}")]
102 ConnectionFailed { addr: String, reason: String },
103
104 #[error("connection closed")]
106 ConnectionClosed,
107
108 #[error("send failed: {0}")]
110 SendFailed(String),
111
112 #[error("receive failed: {0}")]
114 ReceiveFailed(String),
115
116 #[error("tls error: {0}")]
118 Tls(String),
119
120 #[error("invalid address: {0}")]
122 InvalidAddress(String),
123}
124
125#[derive(Error, Debug)]
127pub enum ClusterError {
128 #[error("not a cluster member")]
130 NotMember,
131
132 #[error("gossip error: {0}")]
134 Gossip(String),
135
136 #[error("crdt merge error: {0}")]
138 CrdtMerge(String),
139
140 #[error("node unreachable: {0}")]
142 NodeUnreachable(NodeId),
143}
144
145#[derive(Error, Debug)]
147pub enum ExecutionError {
148 #[error("handler not found for task: {0}")]
150 HandlerNotFound(TaskId),
151
152 #[error("handler panicked: {0}")]
154 HandlerPanic(String),
155
156 #[error("task execution timed out after {0:?}")]
158 Timeout(std::time::Duration),
159
160 #[error("max retries ({max}) exceeded")]
162 MaxRetriesExceeded { max: u32 },
163
164 #[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}