libsql/
errors.rs

1#[derive(Debug, thiserror::Error)]
2#[non_exhaustive]
3pub enum Error {
4    #[error("Failed to connect to database: `{0}`")]
5    ConnectionFailed(String),
6    #[error("SQLite failure: `{1}`")]
7    SqliteFailure(std::ffi::c_int, String),
8    #[error("Null value")]
9    NullValue, // Not in rusqlite
10    #[error("API misuse: `{0}`")]
11    Misuse(String), // Not in rusqlite
12    #[error("Execute returned rows")]
13    ExecuteReturnedRows,
14    #[error("Query returned no rows")]
15    QueryReturnedNoRows,
16    #[error("Invalid column name: `{0}`")]
17    InvalidColumnName(String),
18    #[error("SQL conversion failure: `{0}`")]
19    ToSqlConversionFailure(crate::BoxError),
20    #[error("Sync is not supported in databases opened in {0} mode.")]
21    SyncNotSupported(String), // Not in rusqlite
22    #[error("Loading extension is only supported in local databases.")]
23    LoadExtensionNotSupported, // Not in rusqlite
24    #[error("Authorizer is only supported in local databases.")]
25    AuthorizerNotSupported, // Not in rusqlite
26    #[error("Column not found: {0}")]
27    ColumnNotFound(i32), // Not in rusqlite
28    #[error("Hrana: `{0}`")]
29    Hrana(crate::BoxError), // Not in rusqlite
30    #[error("Write delegation: `{0}`")]
31    WriteDelegation(crate::BoxError), // Not in rusqlite
32    #[error("bincode: `{0}`")]
33    Bincode(crate::BoxError),
34    #[error("invalid column index")]
35    InvalidColumnIndex,
36    #[error("invalid column type")]
37    InvalidColumnType,
38    #[error("syntax error around L{0}:{1}: `{2}`")]
39    Sqlite3SyntaxError(u64, usize, String),
40    #[error("unsupported statement")]
41    Sqlite3UnsupportedStatement,
42    #[error("sqlite3 parser error: `{0}`")]
43    Sqlite3ParserError(crate::BoxError),
44    #[error("Remote SQlite failure: `{0}:{1}:{2}`")]
45    RemoteSqliteFailure(i32, i32, String),
46    #[error("replication error: {0}")]
47    Replication(crate::BoxError),
48    #[error("path has invalid UTF-8")]
49    InvalidUTF8Path,
50    #[error("freeze is not supported in {0} mode.")]
51    FreezeNotSupported(String),
52    #[error("connection has reached an invalid state, started with {0}")]
53    InvalidParserState(String),
54    #[error("TLS error: {0}")]
55    InvalidTlsConfiguration(std::io::Error),
56    #[error("Transactional batch error: {0}")]
57    TransactionalBatchError(String),
58    #[error("Invalid blob size, expected {0}")]
59    InvalidBlobSize(usize),
60    #[error("sync error: {0}")]
61    Sync(crate::BoxError),
62    #[error("WAL frame insert conflict")]
63    WalConflict,
64}
65
66#[cfg(feature = "hrana")]
67impl From<crate::hrana::HranaError> for Error {
68    fn from(e: crate::hrana::HranaError) -> Self {
69        Error::Hrana(e.into())
70    }
71}
72
73#[cfg(feature = "sync")]
74impl From<crate::sync::SyncError> for Error {
75    fn from(e: crate::sync::SyncError) -> Self {
76        Error::Sync(e.into())
77    }
78}
79
80impl From<std::convert::Infallible> for Error {
81    fn from(_: std::convert::Infallible) -> Self {
82        unreachable!()
83    }
84}
85
86#[cfg(feature = "core")]
87pub(crate) fn error_from_handle(raw: *mut libsql_sys::ffi::sqlite3) -> String {
88    let errmsg = unsafe { libsql_sys::ffi::sqlite3_errmsg(raw) };
89    sqlite_errmsg_to_string(errmsg)
90}
91
92#[cfg(feature = "core")]
93pub(crate) fn extended_error_code(raw: *mut libsql_sys::ffi::sqlite3) -> std::ffi::c_int {
94    unsafe { libsql_sys::ffi::sqlite3_extended_errcode(raw) }
95}
96
97#[cfg(feature = "core")]
98pub fn error_from_code(code: i32) -> String {
99    let errmsg = unsafe { libsql_sys::ffi::sqlite3_errstr(code) };
100    sqlite_errmsg_to_string(errmsg)
101}
102
103#[cfg(feature = "core")]
104#[allow(clippy::not_unsafe_ptr_arg_deref)]
105pub fn sqlite_errmsg_to_string(errmsg: *const std::ffi::c_char) -> String {
106    let errmsg = unsafe { std::ffi::CStr::from_ptr(errmsg) }.to_bytes();
107    String::from_utf8_lossy(errmsg).to_string()
108}
109
110#[cfg(feature = "replication")]
111impl From<bincode::Error> for Error {
112    fn from(e: bincode::Error) -> Self {
113        Error::Bincode(e.into())
114    }
115}