chronix_engine/segment/error.rs
1//! Segment error types.
2
3use thiserror::Error;
4
5/// Errors that can occur during segment operations.
6#[derive(Debug, Error)]
7pub enum SegmentError {
8 /// The segment file is corrupt or has an invalid format.
9 #[error("corrupt segment file: {detail}")]
10 CorruptFile {
11 /// Human-readable description of the corruption.
12 detail: String,
13 },
14
15 /// Invalid magic bytes in header or footer.
16 #[error("invalid magic bytes: expected CXSG")]
17 InvalidMagic,
18
19 /// `CRC32c` checksum mismatch.
20 #[error("checksum mismatch: expected {expected:#010x}, got {actual:#010x}")]
21 ChecksumMismatch {
22 /// Expected checksum value.
23 expected: u32,
24 /// Actual computed checksum.
25 actual: u32,
26 },
27
28 /// Unsupported segment version.
29 #[error("unsupported segment version: {version}")]
30 UnsupportedVersion {
31 /// The version number found in the file.
32 version: u16,
33 },
34
35 /// An I/O error occurred.
36 #[error("I/O error: {0}")]
37 Io(#[from] std::io::Error),
38
39 /// An encoding error occurred.
40 #[error("encoding error: {0}")]
41 Encoding(#[from] chronix_encoding::EncodingError),
42
43 /// The segment writer has already been finalized.
44 #[error("segment writer already finalized")]
45 AlreadyFinalized,
46
47 /// No data has been written to the segment.
48 #[error("no data written to segment")]
49 EmptySegment,
50
51 /// Row group index is out of range.
52 #[error("row group index {index} out of range (max: {max})")]
53 RowGroupOutOfRange {
54 /// Requested row group index.
55 index: usize,
56 /// Maximum valid row group index.
57 max: usize,
58 },
59
60 /// Column not found.
61 /// An encrypted column cannot be read because its key is not available.
62 ///
63 /// **Not** [`CorruptFile`](Self::CorruptFile), which is what this used to
64 /// be: nothing is wrong with the bytes. The deployment is missing a key,
65 /// and the two have completely different next steps — one is "restore
66 /// from a backup", the other is "set the environment variable". The
67 /// commonest way to arrive here is restoring an encrypted backup onto a
68 /// machine the key was never given to.
69 #[error(
70 "column '{column}' is encrypted with key '{key_id}', which this database has no \
71 key for — set it under [database.field_encryption] and restart"
72 )]
73 MissingEncryptionKey {
74 /// The column that cannot be read.
75 column: String,
76 /// The key id its blocks were written under.
77 key_id: String,
78 },
79
80 /// The writer was asked for something the format cannot honestly do.
81 ///
82 /// Distinct from [`CorruptFile`](Self::CorruptFile): nothing is wrong
83 /// with the data, the *configuration* is wrong — declaring a tag column
84 /// encrypted, for instance, which the format would accept and which
85 /// would publish the value in the sidecar beside it.
86 #[error("invalid segment writer configuration: {detail}")]
87 InvalidConfiguration {
88 /// What was asked for, and why it cannot be done.
89 detail: String,
90 },
91
92 /// A requested column is not in the segment.
93 #[error("column not found: {name}")]
94 ColumnNotFound {
95 /// The requested column name.
96 name: String,
97 },
98}
99
100/// A specialized `Result` type for segment operations.
101pub type Result<T> = std::result::Result<T, SegmentError>;