Skip to content

Commit 546ec96

Browse files
authored
feat(Sqlite): add LockedSqliteHandle::last_error (#3707)
1 parent 6ca52fe commit 546ec96

File tree

4 files changed

+36
-3
lines changed

4 files changed

+36
-3
lines changed

ci.db

36 KB
Binary file not shown.

sqlx-sqlite/src/connection/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use crate::connection::establish::EstablishParams;
2828
use crate::connection::worker::ConnectionWorker;
2929
use crate::options::OptimizeOnClose;
3030
use crate::statement::VirtualStatement;
31-
use crate::{Sqlite, SqliteConnectOptions};
31+
use crate::{Sqlite, SqliteConnectOptions, SqliteError};
3232

3333
pub(crate) mod collation;
3434
pub(crate) mod describe;
@@ -542,6 +542,10 @@ impl LockedSqliteHandle<'_> {
542542
pub fn remove_rollback_hook(&mut self) {
543543
self.guard.remove_rollback_hook();
544544
}
545+
546+
pub fn last_error(&mut self) -> Option<SqliteError> {
547+
SqliteError::try_new(self.guard.handle.as_ptr())
548+
}
545549
}
546550

547551
impl Drop for ConnectionState {

sqlx-sqlite/src/error.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,17 @@ pub struct SqliteError {
2323

2424
impl SqliteError {
2525
pub(crate) fn new(handle: *mut sqlite3) -> Self {
26+
Self::try_new(handle).expect("There should be an error")
27+
}
28+
29+
pub(crate) fn try_new(handle: *mut sqlite3) -> Option<Self> {
2630
// returns the extended result code even when extended result codes are disabled
2731
let code: c_int = unsafe { sqlite3_extended_errcode(handle) };
2832

33+
if code == 0 {
34+
return None;
35+
}
36+
2937
// return English-language text that describes the error
3038
let message = unsafe {
3139
let msg = sqlite3_errmsg(handle);
@@ -34,10 +42,10 @@ impl SqliteError {
3442
from_utf8_unchecked(CStr::from_ptr(msg).to_bytes())
3543
};
3644

37-
Self {
45+
Some(Self {
3846
code,
3947
message: message.to_owned(),
40-
}
48+
})
4149
}
4250

4351
/// For errors during extension load, the error message is supplied via a separate pointer

tests/sqlite/sqlite.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,3 +1172,24 @@ async fn test_multiple_set_preupdate_hook_calls_drop_old_handler() -> anyhow::Re
11721172
assert_eq!(1, Arc::strong_count(&ref_counted_object));
11731173
Ok(())
11741174
}
1175+
1176+
#[sqlx_macros::test]
1177+
async fn test_get_last_error() -> anyhow::Result<()> {
1178+
let mut conn = new::<Sqlite>().await?;
1179+
1180+
let _ = sqlx::query("select 1").fetch_one(&mut conn).await?;
1181+
1182+
{
1183+
let mut handle = conn.lock_handle().await?;
1184+
assert!(handle.last_error().is_none());
1185+
}
1186+
1187+
let _ = sqlx::query("invalid statement").fetch_one(&mut conn).await;
1188+
1189+
{
1190+
let mut handle = conn.lock_handle().await?;
1191+
assert!(handle.last_error().is_some());
1192+
}
1193+
1194+
Ok(())
1195+
}

0 commit comments

Comments
 (0)