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}