noxu_log/error.rs
1//! Error types for the log layer.
2//!
3
4use std::io;
5use thiserror::Error;
6
7/// Errors that can occur in the log layer.
8#[derive(Debug, Error)]
9pub enum NoxuLogError {
10 /// I/O error during file operations.
11 #[error("Log I/O error: {0}")]
12 Io(#[from] io::Error),
13
14 /// File not found (specific log file).
15 #[error("Log file not found: {0}")]
16 FileNotFound(String),
17
18 /// Checksum validation failed.
19 #[error("Checksum validation failed at LSN {lsn}: {message}")]
20 Checksum { lsn: noxu_util::lsn::Lsn, message: String },
21
22 /// Invalid file header.
23 #[error("Invalid file header in file {file_num:08x}: {message}")]
24 InvalidHeader { file_num: u32, message: String },
25
26 /// Version mismatch between log file and current version.
27 #[error(
28 "Version mismatch: expected {expected}, found {found} in file {file_num:08x}"
29 )]
30 VersionMismatch { expected: u32, found: u32, file_num: u32 },
31
32 /// Environment is locked by another process.
33 #[error("Environment locked: {0}")]
34 EnvironmentLocked(String),
35
36 /// Invalid environment directory.
37 #[error("Invalid environment directory: {0}")]
38 InvalidDirectory(String),
39
40 /// Log write failed.
41 #[error("Log write failed: {0}")]
42 WriteFailed(String),
43
44 /// Invalid entry type number.
45 #[error("Invalid entry type {type_num} at LSN {lsn}")]
46 InvalidEntryType { type_num: u8, lsn: noxu_util::lsn::Lsn },
47
48 /// Invalid entry size.
49 #[error("Invalid entry size {size} at LSN {lsn}")]
50 InvalidEntrySize { size: i32, lsn: noxu_util::lsn::Lsn },
51
52 /// Unexpected end of data.
53 #[error("Unexpected EOF at LSN {lsn}: {message}")]
54 UnexpectedEof { lsn: noxu_util::lsn::Lsn, message: String },
55
56 /// Buffer overflow.
57 #[error("Buffer overflow: {0}")]
58 BufferOverflow(String),
59
60 /// Log corruption detected.
61 #[error("Log corrupt: {0}")]
62 LogCorrupt(String),
63
64 /// File header CRC32 checksum mismatch (torn header write).
65 ///
66 /// Returned when a v3 file header is opened and the trailing 4-byte
67 /// CRC32 over bytes `[0..32]` does not match the stored value. A torn
68 /// header write can corrupt `file_number` or `last_entry_in_prev_file`
69 /// while leaving magic + version intact; this error makes such corruption
70 /// detectable rather than silently yielding wrong recovery metadata.
71 #[error(
72 "Header CRC32 mismatch in file {file_num:08x}: \
73 expected {expected:#010x}, found {found:#010x}"
74 )]
75 HeaderChecksumMismatch { file_num: u32, expected: u32, found: u32 },
76
77 /// Latch acquisition timed out (maps to EnvironmentFailure/LatchTimeout).
78 #[error("Latch acquisition timed out: {0}")]
79 LatchTimeout(String),
80
81 /// A committed transaction was found AFTER a mid-file corruption point.
82 ///
83 /// Surfaced by [`crate::last_file_reader::LastFileReader`] during
84 /// end-of-log discovery when the `haltOnCommitAfterChecksumException`
85 /// param is enabled and a `TxnCommit` entry exists past a checksum
86 /// failure. This distinguishes real media corruption (with committed
87 /// data beyond it) from a benign torn-tail write — recovery must REFUSE
88 /// to silently truncate. Recovery maps this to the env-invalidating
89 /// `EnvironmentFailureReason::FoundCommittedTxn`.
90 ///
91 /// Faithful to JE `LastFileReader.readNextEntry`/`findCommittedTxn`
92 /// (LastFileReader.java:313/394, [#18307]) which throws
93 /// `EnvironmentFailureException(FOUND_COMMITTED_TXN, ...)`.
94 #[error(
95 "Found committed txn after the corruption point: \
96 corrupt entry at LSN {corrupt_lsn}, committed txn at LSN {commit_lsn}"
97 )]
98 FoundCommittedTxn {
99 corrupt_lsn: noxu_util::lsn::Lsn,
100 commit_lsn: noxu_util::lsn::Lsn,
101 },
102
103 /// Internal consistency error.
104 #[error("Internal error: {0}")]
105 Internal(String),
106}
107
108/// Alias for backward compatibility with code using `LogError`.
109pub type LogError = NoxuLogError;
110
111pub type Result<T> = std::result::Result<T, NoxuLogError>;