1use thiserror::Error;
2
3#[derive(Debug, Error, miette::Diagnostic)]
4pub enum LimboError {
5 #[error("Corrupt database: {0}")]
6 Corrupt(String),
7 #[error("File is not a database")]
8 NotADB,
9 #[error("Internal error: {0}")]
10 InternalError(String),
11 #[error("Page cache is full")]
12 CacheFull,
13 #[error("Parse error: {0}")]
14 ParseError(String),
15 #[error(transparent)]
16 #[diagnostic(transparent)]
17 LexerError(#[from] limbo_sqlite3_parser::lexer::sql::Error),
18 #[error("Conversion error: {0}")]
19 ConversionError(String),
20 #[error("Env variable error: {0}")]
21 EnvVarError(#[from] std::env::VarError),
22 #[error("Transaction error: {0}")]
23 TxError(String),
24 #[error("I/O error: {0}")]
25 IOError(#[from] std::io::Error),
26 #[cfg(all(target_os = "linux", feature = "io_uring"))]
27 #[error("I/O error: {0}")]
28 UringIOError(String),
29 #[error("Locking error: {0}")]
30 LockingError(String),
31 #[cfg(target_family = "unix")]
32 #[error("I/O error: {0}")]
33 RustixIOError(#[from] rustix::io::Errno),
34 #[error("Parse error: {0}")]
35 ParseIntError(#[from] std::num::ParseIntError),
36 #[error("Parse error: {0}")]
37 ParseFloatError(#[from] std::num::ParseFloatError),
38 #[error("Parse error: {0}")]
39 InvalidDate(String),
40 #[error("Parse error: {0}")]
41 InvalidTime(String),
42 #[error("Modifier parsing error: {0}")]
43 InvalidModifier(String),
44 #[error("Invalid argument supplied: {0}")]
45 InvalidArgument(String),
46 #[error("Invalid formatter supplied: {0}")]
47 InvalidFormatter(String),
48 #[error("Runtime error: {0}")]
49 Constraint(String),
50 #[error("Extension error: {0}")]
51 ExtensionError(String),
52 #[error("Runtime error: integer overflow")]
53 IntegerOverflow,
54 #[error("Schema is locked for write")]
55 SchemaLocked,
56 #[error("database schema has changed")]
57 SchemaChanged,
58 #[error("Database Connection is read-only")]
59 ReadOnly,
60 #[error("Database is busy")]
61 Busy,
62}
63
64#[macro_export]
65macro_rules! bail_parse_error {
66 ($($arg:tt)*) => {
67 return Err($crate::error::LimboError::ParseError(format!($($arg)*)))
68 };
69}
70
71#[macro_export]
72macro_rules! bail_corrupt_error {
73 ($($arg:tt)*) => {
74 return Err($crate::error::LimboError::Corrupt(format!($($arg)*)))
75 };
76}
77
78#[macro_export]
79macro_rules! bail_constraint_error {
80 ($($arg:tt)*) => {
81 return Err($crate::error::LimboError::Constraint(format!($($arg)*)))
82 };
83}
84
85impl From<limbo_ext::ResultCode> for LimboError {
86 fn from(err: limbo_ext::ResultCode) -> Self {
87 LimboError::ExtensionError(err.to_string())
88 }
89}
90
91pub const SQLITE_CONSTRAINT: usize = 19;
92pub const SQLITE_CONSTRAINT_PRIMARYKEY: usize = SQLITE_CONSTRAINT | (6 << 8);
93pub const SQLITE_CONSTRAINT_NOTNULL: usize = SQLITE_CONSTRAINT | (5 << 8);