mnemo_engine/error.rs
1//! Error types for Mnemo.
2
3use thiserror::Error;
4
5/// All errors the Mnemo engine can produce.
6#[derive(Error, Debug)]
7pub enum MnemoError {
8 /// An underlying I/O failure.
9 #[error("io error: {0}")]
10 Io(#[from] std::io::Error),
11
12 /// The file does not begin with the Mnemo magic bytes.
13 #[error("bad magic bytes — file is not a .mnemo database")]
14 BadMagic,
15
16 /// The on-disk format version is newer than this build understands.
17 #[error("unsupported .mnemo format version {0} (this build supports v1)")]
18 UnsupportedVersion(u16),
19
20 /// The header page failed its CRC check — a torn page-0 write or
21 /// corruption. [`crate::Mnemo::open`] tries to repair this from the WAL.
22 #[error("header checksum mismatch — page 0 is torn or corrupt")]
23 HeaderChecksum,
24
25 /// Returned when the supplied passphrase fails to unwrap the data key.
26 /// The failure is an authenticated-decryption failure, so it is
27 /// indistinguishable from a tampered key blob — both are rejected cleanly.
28 #[error("wrong passphrase, or the key material has been tampered with")]
29 WrongPassphrase,
30
31 /// AEAD authentication failed for a page: corruption or tampering.
32 #[error("page {0} failed authentication — the file is corrupt or tampered")]
33 PageAuthFailed(u64),
34
35 /// The v7 header seal failed authentication — at least one mutable
36 /// header field has been rewritten without the DEK. Open refuses to
37 /// proceed so a silent rollback or pointer-rewrite attack can't
38 /// surface stale data.
39 #[error("header seal authentication failed — mutable fields tampered with")]
40 HeaderTampered,
41
42 /// A low-level cryptographic operation failed.
43 #[error("cryptographic operation failed: {0}")]
44 Crypto(String),
45
46 /// Argon2id key derivation failed.
47 #[error("key derivation failed: {0}")]
48 Kdf(String),
49
50 /// A record failed to (de)serialize.
51 #[error("serialization error: {0}")]
52 Serialize(String),
53
54 /// No memory exists with the requested ID.
55 #[error("memory '{0}' not found")]
56 NotFound(String),
57
58 /// A vector did not match the database's configured dimensionality.
59 #[error("vector dimension mismatch: database expects {expected}, got {got}")]
60 DimensionMismatch {
61 /// Dimensionality the database was created with.
62 expected: usize,
63 /// Dimensionality of the offending vector.
64 got: usize,
65 },
66
67 /// A caller-supplied argument was invalid.
68 #[error("invalid argument: {0}")]
69 Invalid(String),
70
71 /// Another process (or another handle in this process) already holds a
72 /// conflicting OS file lock on the target `.mnemo` file. Write handles
73 /// take an exclusive lock; read-only handles take a shared lock. Two
74 /// writers or a writer + reader will collide.
75 #[error("file already locked by another handle: {path}")]
76 Locked {
77 /// The path whose lock was requested and refused.
78 path: std::path::PathBuf,
79 },
80
81 /// A mutation was attempted on a handle opened via
82 /// [`crate::Mnemo::open_read_only`]. Reopen read-write to mutate.
83 #[error("operation requires a read-write handle (this one is read-only)")]
84 ReadOnly,
85
86 /// A read-only open was requested but the file has pending on-disk work
87 /// that requires a write handle to complete — a committed-but-unchecked
88 /// WAL transaction, or a format-version migration older than the current
89 /// `VERSION`. Open read-write once, close cleanly, then reopen read-only.
90 #[error("read-only open blocked: {reason} — open read-write once to fix")]
91 NeedsWriteOpen {
92 /// Human-readable reason (e.g. `"pending WAL recovery"`).
93 reason: &'static str,
94 },
95}
96
97/// Convenience result alias used throughout the crate.
98pub type Result<T> = std::result::Result<T, MnemoError>;