laminar_core/
error_codes.rs1pub const INVALID_CONFIG: &str = "LDB-0001";
30pub const MISSING_CONFIG: &str = "LDB-0002";
32pub const UNRESOLVED_CONFIG_VAR: &str = "LDB-0003";
34pub const SHUTDOWN: &str = "LDB-0004";
36pub const INVALID_OPERATION: &str = "LDB-0005";
38pub const SCHEMA_MISMATCH: &str = "LDB-0006";
40
41pub const SQL_UNSUPPORTED: &str = "LDB-1001";
47pub const SQL_PLANNING_FAILED: &str = "LDB-1002";
49pub const SQL_COLUMN_NOT_FOUND: &str = "LDB-1100";
51pub const SQL_TABLE_NOT_FOUND: &str = "LDB-1101";
53pub const SQL_TYPE_MISMATCH: &str = "LDB-1200";
55
56pub const WATERMARK_REQUIRED: &str = "LDB-2001";
60pub const WINDOW_INVALID: &str = "LDB-2002";
62pub const WINDOW_SIZE_INVALID: &str = "LDB-2003";
64pub const LATE_DATA_REJECTED: &str = "LDB-2004";
66
67pub const JOIN_KEY_MISSING: &str = "LDB-3001";
71pub const JOIN_TIME_BOUND_MISSING: &str = "LDB-3002";
73pub const TEMPORAL_JOIN_NO_PK: &str = "LDB-3003";
75pub const JOIN_TYPE_UNSUPPORTED: &str = "LDB-3004";
77
78pub const SERIALIZATION_FAILED: &str = "LDB-4001";
82pub const DESERIALIZATION_FAILED: &str = "LDB-4002";
84pub const JSON_PARSE_ERROR: &str = "LDB-4003";
86pub const BASE64_DECODE_ERROR: &str = "LDB-4004";
88pub const STATE_KEY_MISSING: &str = "LDB-4005";
90pub const STATE_CORRUPTION: &str = "LDB-4006";
92
93pub const CONNECTOR_CONNECTION_FAILED: &str = "LDB-5001";
97pub const CONNECTOR_AUTH_FAILED: &str = "LDB-5002";
99pub const CONNECTOR_READ_ERROR: &str = "LDB-5003";
101pub const CONNECTOR_WRITE_ERROR: &str = "LDB-5004";
103pub const CONNECTOR_CONFIG_ERROR: &str = "LDB-5005";
105pub const SOURCE_NOT_FOUND: &str = "LDB-5010";
107pub const SINK_NOT_FOUND: &str = "LDB-5011";
109pub const SOURCE_ALREADY_EXISTS: &str = "LDB-5012";
111pub const SINK_ALREADY_EXISTS: &str = "LDB-5013";
113pub const CONNECTOR_SERDE_ERROR: &str = "LDB-5020";
115pub const CONNECTOR_SCHEMA_ERROR: &str = "LDB-5021";
117
118pub const CHECKPOINT_FAILED: &str = "LDB-6001";
122pub const CHECKPOINT_NOT_FOUND: &str = "LDB-6002";
124pub const RECOVERY_FAILED: &str = "LDB-6003";
126pub const SINK_ROLLBACK_FAILED: &str = "LDB-6004";
128pub const WAL_ERROR: &str = "LDB-6005";
130pub const WAL_INVALID_LENGTH: &str = "LDB-6006";
132pub const WAL_CHECKSUM_MISMATCH: &str = "LDB-6007";
134pub const MANIFEST_PERSIST_FAILED: &str = "LDB-6008";
136pub const CHECKPOINT_PRUNE_FAILED: &str = "LDB-6009";
138pub const SIDECAR_CORRUPTION: &str = "LDB-6010";
140pub const OFFSET_METADATA_MISSING: &str = "LDB-6011";
142
143pub const QUERY_EXECUTION_FAILED: &str = "LDB-7001";
149pub const ARROW_ERROR: &str = "LDB-7002";
151pub const PLAN_OPTIMIZATION_FAILED: &str = "LDB-7003";
153
154pub const INTERNAL: &str = "LDB-8001";
158pub const PIPELINE_ERROR: &str = "LDB-8002";
160pub const MATERIALIZED_VIEW_ERROR: &str = "LDB-8003";
162pub const QUERY_PIPELINE_ERROR: &str = "LDB-8004";
164
165#[derive(Debug, Clone, Copy, PartialEq, Eq)]
172#[repr(u16)]
173pub enum HotPathError {
174 LateEvent = 0x0001,
176 StateKeyMissing = 0x0002,
178 Backpressure = 0x0003,
180 SerializationOverflow = 0x0004,
182 SchemaMismatch = 0x0005,
184 AggregateStateCorruption = 0x0006,
186 QueueFull = 0x0007,
188 ChannelClosed = 0x0008,
190}
191
192impl HotPathError {
193 #[must_use]
195 pub const fn message(self) -> &'static str {
196 match self {
197 Self::LateEvent => "Event arrived after watermark; dropped",
198 Self::StateKeyMissing => "State key not found in store",
199 Self::Backpressure => "Downstream backpressure; event buffered",
200 Self::SerializationOverflow => "Serialization buffer capacity exceeded",
201 Self::SchemaMismatch => "Record batch schema does not match expected",
202 Self::AggregateStateCorruption => "Aggregate state checksum mismatch detected",
203 Self::QueueFull => "Queue is full; cannot push event",
204 Self::ChannelClosed => "Channel is closed or disconnected",
205 }
206 }
207
208 #[must_use]
210 pub const fn code(self) -> u16 {
211 self as u16
212 }
213
214 #[must_use]
216 pub const fn ldb_code(self) -> &'static str {
217 match self {
218 Self::LateEvent => LATE_DATA_REJECTED,
219 Self::StateKeyMissing => STATE_KEY_MISSING,
220 Self::Backpressure => "LDB-8010",
221 Self::SerializationOverflow => SERIALIZATION_FAILED,
222 Self::SchemaMismatch => SCHEMA_MISMATCH,
223 Self::AggregateStateCorruption => STATE_CORRUPTION,
224 Self::QueueFull => "LDB-8011",
225 Self::ChannelClosed => "LDB-8012",
226 }
227 }
228}
229
230impl std::fmt::Display for HotPathError {
231 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
232 write!(f, "[{}] {}", self.ldb_code(), self.message())
233 }
234}
235
236impl std::error::Error for HotPathError {}
237
238#[cfg(test)]
239mod tests {
240 use super::*;
241
242 #[test]
243 fn hot_path_error_is_copy_and_small() {
244 let e = HotPathError::LateEvent;
245 let e2 = e; assert_eq!(e, e2);
247 assert_eq!(std::mem::size_of::<HotPathError>(), 2);
248 }
249
250 #[test]
251 fn hot_path_error_codes_are_nonzero() {
252 let variants = [
253 HotPathError::LateEvent,
254 HotPathError::StateKeyMissing,
255 HotPathError::Backpressure,
256 HotPathError::SerializationOverflow,
257 HotPathError::SchemaMismatch,
258 HotPathError::AggregateStateCorruption,
259 HotPathError::QueueFull,
260 HotPathError::ChannelClosed,
261 ];
262 for v in &variants {
263 assert!(v.code() > 0, "{v:?} has zero code");
264 assert!(!v.message().is_empty(), "{v:?} has empty message");
265 assert!(
266 v.ldb_code().starts_with("LDB-"),
267 "{v:?} has bad ldb_code: {}",
268 v.ldb_code()
269 );
270 }
271 }
272
273 #[test]
274 fn hot_path_error_display() {
275 let e = HotPathError::LateEvent;
276 let s = e.to_string();
277 assert!(s.starts_with("[LDB-"));
278 assert!(s.contains("watermark"));
279 }
280
281 #[test]
282 fn error_codes_are_stable_strings() {
283 assert_eq!(INVALID_CONFIG, "LDB-0001");
284 assert_eq!(SERIALIZATION_FAILED, "LDB-4001");
285 assert_eq!(CHECKPOINT_FAILED, "LDB-6001");
286 assert_eq!(INTERNAL, "LDB-8001");
287 }
288}