lsm_tree/
error.rs

1// Copyright (c) 2024-present, fjall-rs
2// This source code is licensed under both the Apache 2.0 and MIT License
3// (found in the LICENSE-* files in the repository)
4
5use crate::{
6    coding::{DecodeError, EncodeError},
7    format_version::FormatVersion,
8    Checksum, CompressionType,
9};
10
11/// Represents errors that can occur in the LSM-tree
12#[derive(Debug)]
13#[non_exhaustive]
14pub enum Error {
15    /// I/O error
16    Io(std::io::Error),
17
18    /// Serialization failed
19    Encode(EncodeError),
20
21    /// Deserialization failed
22    Decode(DecodeError),
23
24    /// Decompression failed
25    Decompress(CompressionType),
26
27    /// Invalid or unparsable data format version
28    InvalidVersion(FormatVersion),
29
30    /// Some required segments could not be recovered from disk
31    Unrecoverable,
32
33    /// Checksum mismatch
34    ChecksumMismatch {
35        /// Checksum of loaded block
36        got: Checksum,
37
38        /// Checksum that was saved in block header
39        expected: Checksum,
40    },
41}
42
43impl std::fmt::Display for Error {
44    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
45        write!(f, "LsmTreeError: {self:?}")
46    }
47}
48
49impl std::error::Error for Error {
50    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
51        match self {
52            Self::Io(e) => Some(e),
53            Self::Encode(e) => Some(e),
54            Self::Decode(e) => Some(e),
55            Self::Decompress(_)
56            | Self::InvalidVersion(_)
57            | Self::Unrecoverable
58            | Self::ChecksumMismatch { .. } => None,
59        }
60    }
61}
62
63impl From<sfa::Error> for Error {
64    fn from(value: sfa::Error) -> Self {
65        match value {
66            sfa::Error::Io(e) => Self::from(e),
67            sfa::Error::ChecksumMismatch { got, expected } => {
68                log::error!("Archive ToC checksum mismatch");
69                Self::ChecksumMismatch {
70                    got: got.into(),
71                    expected: expected.into(),
72                }
73            }
74            sfa::Error::InvalidHeader => {
75                log::error!("Invalid archive header");
76                Self::Unrecoverable
77            }
78            sfa::Error::InvalidVersion => {
79                log::error!("Invalid archive version");
80                Self::Unrecoverable
81            }
82            sfa::Error::UnsupportedChecksumType => {
83                log::error!("Invalid archive checksum type");
84                Self::Unrecoverable
85            }
86        }
87    }
88}
89
90impl From<std::io::Error> for Error {
91    fn from(value: std::io::Error) -> Self {
92        Self::Io(value)
93    }
94}
95
96impl From<EncodeError> for Error {
97    fn from(value: EncodeError) -> Self {
98        Self::Encode(value)
99    }
100}
101
102impl From<DecodeError> for Error {
103    fn from(value: DecodeError) -> Self {
104        Self::Decode(value)
105    }
106}
107
108/// Tree result
109pub type Result<T> = std::result::Result<T, Error>;