reth_storage_errors/
db.rs

1use alloc::{
2    boxed::Box,
3    format,
4    string::{String, ToString},
5    vec::Vec,
6};
7use core::{
8    fmt::{Debug, Display},
9    str::FromStr,
10};
11
12/// Database error type.
13#[derive(Clone, Debug, PartialEq, Eq, thiserror::Error)]
14pub enum DatabaseError {
15    /// Failed to open the database.
16    #[error("failed to open the database: {_0}")]
17    Open(DatabaseErrorInfo),
18    /// Failed to create a table in the database.
19    #[error("failed to create a table: {_0}")]
20    CreateTable(DatabaseErrorInfo),
21    /// Failed to write a value into a table.
22    #[error(transparent)]
23    Write(Box<DatabaseWriteError>),
24    /// Failed to read a value from a table.
25    #[error("failed to read a value from a database table: {_0}")]
26    Read(DatabaseErrorInfo),
27    /// Failed to delete a `(key, value)` pair from a table.
28    #[error("database delete error code: {_0}")]
29    Delete(DatabaseErrorInfo),
30    /// Failed to commit transaction changes into the database.
31    #[error("failed to commit transaction changes: {_0}")]
32    Commit(DatabaseErrorInfo),
33    /// Failed to initiate a transaction.
34    #[error("failed to initialize a transaction: {_0}")]
35    InitTx(DatabaseErrorInfo),
36    /// Failed to initialize a cursor.
37    #[error("failed to initialize a cursor: {_0}")]
38    InitCursor(DatabaseErrorInfo),
39    /// Failed to decode a key from a table.
40    #[error("failed to decode a key from a table")]
41    Decode,
42    /// Failed to get database stats.
43    #[error("failed to get stats: {_0}")]
44    Stats(DatabaseErrorInfo),
45    /// Failed to use the specified log level, as it's not available.
46    #[error("log level {_0:?} is not available")]
47    LogLevelUnavailable(LogLevel),
48    /// Other unspecified error.
49    #[error("{_0}")]
50    Other(String),
51}
52
53/// Common error struct to propagate implementation-specific error information.
54#[derive(Debug, Clone, PartialEq, Eq, derive_more::Display)]
55#[display("{message} ({code})")]
56pub struct DatabaseErrorInfo {
57    /// Human-readable error message.
58    pub message: Box<str>,
59    /// Error code.
60    pub code: i32,
61}
62
63impl<E> From<E> for DatabaseErrorInfo
64where
65    E: Display + Into<i32>,
66{
67    #[inline]
68    fn from(error: E) -> Self {
69        Self { message: error.to_string().into(), code: error.into() }
70    }
71}
72
73impl From<DatabaseWriteError> for DatabaseError {
74    #[inline]
75    fn from(error: DatabaseWriteError) -> Self {
76        Self::Write(Box::new(error))
77    }
78}
79
80/// Database write error.
81#[derive(Clone, Debug, PartialEq, Eq, thiserror::Error)]
82#[error("write operation {:?} failed for key \"{}\" in table {}: {}",
83            self.operation,
84            alloy_primitives::hex::encode(&self.key),
85            self.table_name,
86            self.info)]
87pub struct DatabaseWriteError {
88    /// The error code and message.
89    pub info: DatabaseErrorInfo,
90    /// The write operation type.
91    pub operation: DatabaseWriteOperation,
92    /// The table name.
93    pub table_name: &'static str,
94    /// The write key.
95    pub key: Vec<u8>,
96}
97
98/// Database write operation type.
99#[derive(Clone, Copy, Debug, PartialEq, Eq)]
100pub enum DatabaseWriteOperation {
101    /// Append cursor.
102    CursorAppend,
103    /// Upsert cursor.
104    CursorUpsert,
105    /// Insert cursor.
106    CursorInsert,
107    /// Append duplicate cursor.
108    CursorAppendDup,
109    /// Put.
110    Put,
111}
112
113/// Database log level.
114#[derive(Debug, PartialEq, Eq, Clone, Copy)]
115pub enum LogLevel {
116    /// Enables logging for critical conditions, i.e. assertion failures.
117    Fatal,
118    /// Enables logging for error conditions.
119    Error,
120    /// Enables logging for warning conditions.
121    Warn,
122    /// Enables logging for normal but significant condition.
123    Notice,
124    /// Enables logging for verbose informational.
125    Verbose,
126    /// Enables logging for debug-level messages.
127    Debug,
128    /// Enables logging for trace debug-level messages.
129    Trace,
130    /// Enables logging for extra debug-level messages.
131    Extra,
132}
133
134impl LogLevel {
135    /// All possible variants of the `LogLevel` enum
136    pub const fn value_variants() -> &'static [Self] {
137        &[
138            Self::Fatal,
139            Self::Error,
140            Self::Warn,
141            Self::Notice,
142            Self::Verbose,
143            Self::Debug,
144            Self::Trace,
145            Self::Extra,
146        ]
147    }
148
149    /// Static str reference to `LogLevel` enum, required for `Clap::Builder::PossibleValue::new()`
150    pub const fn variant_name(&self) -> &'static str {
151        match self {
152            Self::Fatal => "fatal",
153            Self::Error => "error",
154            Self::Warn => "warn",
155            Self::Notice => "notice",
156            Self::Verbose => "verbose",
157            Self::Debug => "debug",
158            Self::Trace => "trace",
159            Self::Extra => "extra",
160        }
161    }
162
163    /// Returns all variants descriptions
164    pub const fn help_message(&self) -> &'static str {
165        match self {
166            Self::Fatal => "Enables logging for critical conditions, i.e. assertion failures",
167            Self::Error => "Enables logging for error conditions",
168            Self::Warn => "Enables logging for warning conditions",
169            Self::Notice => "Enables logging for normal but significant condition",
170            Self::Verbose => "Enables logging for verbose informational",
171            Self::Debug => "Enables logging for debug-level messages",
172            Self::Trace => "Enables logging for trace debug-level messages",
173            Self::Extra => "Enables logging for extra debug-level messages",
174        }
175    }
176}
177
178impl FromStr for LogLevel {
179    type Err = String;
180
181    fn from_str(s: &str) -> Result<Self, Self::Err> {
182        match s.to_lowercase().as_str() {
183            "fatal" => Ok(Self::Fatal),
184            "error" => Ok(Self::Error),
185            "warn" => Ok(Self::Warn),
186            "notice" => Ok(Self::Notice),
187            "verbose" => Ok(Self::Verbose),
188            "debug" => Ok(Self::Debug),
189            "trace" => Ok(Self::Trace),
190            "extra" => Ok(Self::Extra),
191            _ => Err(format!("Invalid log level: {s}")),
192        }
193    }
194}