fluxmap/error.rs
1//! Defines the error types used throughout FluxMap.
2use std::fmt;
3use std::io;
4
5/// The primary error enum for all fallible operations in FluxMap.
6#[derive(Debug, PartialEq, Eq)]
7pub enum FluxError {
8 /// Represents a serialization error, which occurs when a transaction cannot be
9 /// committed because it conflicts with another concurrent transaction. This is
10 /// essential for maintaining Serializable Snapshot Isolation (SSI).
11 ///
12 /// This error indicates that a transaction was rolled back to prevent a write-skew
13 /// or other anomaly. The operation can typically be safely retried.
14 SerializationConflict,
15 /// Occurs when `begin()` is called on a `Handle` that already has an active transaction.
16 /// A handle can only manage one transaction at a time.
17 TransactionAlreadyActive,
18 /// Occurs when `commit()` or `rollback()` is called on a `Handle` with no active transaction.
19 NoActiveTransaction,
20 /// A specified savepoint name was not found within the active transaction.
21 SavepointNotFound(String),
22 /// Wraps an error originating from the persistence layer.
23 Persistence(PersistenceError),
24 /// Represents an error during the key eviction process, e.g., no victim could be found.
25 EvictionError,
26 /// Represents an error in the database configuration.
27 Configuration(String),
28 /// The database has exceeded its configured memory limit and requires manual eviction.
29 /// This error is only returned when the `EvictionPolicy` is set to `Manual`.
30 MemoryLimitExceeded,
31 /// A fatal, unrecoverable error occurred in a background task, such as the persistence engine.
32 /// The database is in an indeterminate state and cannot accept further operations.
33 FatalPersistenceError(String),
34}
35
36/// A specific error originating from the persistence layer.
37#[derive(Debug, PartialEq, Eq)]
38pub enum PersistenceError {
39 /// An underlying I/O error from the filesystem.
40 Io(String),
41 /// An error during data serialization or deserialization (e.g., for the WAL or snapshots).
42 Serialization(String),
43 /// An error that occurred during the database recovery process.
44 Recovery(String),
45}
46
47impl fmt::Display for PersistenceError {
48 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49 match self {
50 PersistenceError::Io(e) => write!(f, "I/O error: {}", e),
51 PersistenceError::Serialization(e) => write!(f, "Serialization error: {}", e),
52 PersistenceError::Recovery(e) => write!(f, "Recovery error: {}", e),
53 }
54 }
55}
56
57impl std::error::Error for PersistenceError {}
58
59impl fmt::Display for FluxError {
60 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61 match self {
62 FluxError::SerializationConflict => {
63 write!(f, "Serialization conflict: transaction aborted")
64 }
65 FluxError::TransactionAlreadyActive => {
66 write!(f, "A transaction is already active on this handle")
67 }
68 FluxError::NoActiveTransaction => {
69 write!(f, "No active transaction on this handle")
70 }
71 FluxError::SavepointNotFound(name) => {
72 write!(f, "Savepoint '{}' not found in active transaction", name)
73 }
74 FluxError::Persistence(e) => write!(f, "Persistence error: {}", e),
75 FluxError::EvictionError => write!(f, "Eviction error: could not find or evict a key"),
76 FluxError::MemoryLimitExceeded => {
77 write!(f, "Memory limit exceeded, manual eviction required")
78 }
79 FluxError::Configuration(e) => write!(f, "Configuration error: {}", e),
80 FluxError::FatalPersistenceError(e) => {
81 write!(
82 f,
83 "Fatal persistence error: {}. The database is in a terminal state.",
84 e
85 )
86 }
87 }
88 }
89}
90
91impl std::error::Error for FluxError {}
92
93impl From<io::Error> for FluxError {
94 fn from(err: io::Error) -> Self {
95 FluxError::Persistence(PersistenceError::Io(err.to_string()))
96 }
97}