From d142c00a1c36d676a61c716bab18fe5d583350ce Mon Sep 17 00:00:00 2001 From: gwenn Date: Fri, 6 Dec 2024 21:19:42 +0100 Subject: [PATCH 1/3] Use sqlite3_errstr when `sqlite3_errcode` doesn't match result code. Mostly with SQLITE_MISUSE. --- src/error.rs | 24 ++++++++++++++++-------- src/statement.rs | 7 ++++++- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/error.rs b/src/error.rs index bb46e2d..f5b4e28 100644 --- a/src/error.rs +++ b/src/error.rs @@ -130,7 +130,7 @@ pub enum Error { /// error code error: ffi::Error, /// error message - msg: String, + msg: Option, /// SQL input sql: String, /// byte offset of the start of invalid token @@ -324,7 +324,7 @@ impl fmt::Display for Error { offset, ref sql, .. - } => write!(f, "{msg} in {sql} at offset {offset}"), + } => write!(f, "{msg:?} in {sql} at offset {offset}"), #[cfg(feature = "loadable_extension")] Self::InitError(ref err) => err.fmt(f), #[cfg(feature = "modern_sqlite")] @@ -414,12 +414,20 @@ pub fn error_from_sqlite_code(code: c_int, message: Option) -> Error { #[cold] pub unsafe fn error_from_handle(db: *mut ffi::sqlite3, code: c_int) -> Error { - let message = if db.is_null() { - None + error_from_sqlite_code(code, error_msg(db, code)) +} + +unsafe fn error_msg(db: *mut ffi::sqlite3, code: c_int) -> Option { + if db.is_null() || ffi::sqlite3_errcode(db) != code { + let err_str = ffi::sqlite3_errstr(code); + if err_str.is_null() { + None + } else { + Some(errmsg_to_string(err_str)) + } } else { Some(errmsg_to_string(ffi::sqlite3_errmsg(db))) - }; - error_from_sqlite_code(code, message) + } } pub unsafe fn decode_result_raw(db: *mut ffi::sqlite3, code: c_int) -> Result<()> { @@ -443,7 +451,7 @@ pub unsafe fn error_with_offset(db: *mut ffi::sqlite3, code: c_int, sql: &str) - error_from_sqlite_code(code, None) } else { let error = ffi::Error::new(code); - let msg = errmsg_to_string(ffi::sqlite3_errmsg(db)); + let msg = error_msg(db, code); if ffi::ErrorCode::Unknown == error.code { let offset = ffi::sqlite3_error_offset(db); if offset >= 0 { @@ -455,7 +463,7 @@ pub unsafe fn error_with_offset(db: *mut ffi::sqlite3, code: c_int, sql: &str) - }; } } - Error::SqliteFailure(error, Some(msg)) + Error::SqliteFailure(error, msg) } } diff --git a/src/statement.rs b/src/statement.rs index b11c31b..02cf72e 100644 --- a/src/statement.rs +++ b/src/statement.rs @@ -1286,7 +1286,12 @@ mod test { let mut stmt = conn.prepare("")?; assert_eq!(0, stmt.column_count()); stmt.parameter_index("test")?; - stmt.step().unwrap_err(); + let err = stmt.step().unwrap_err(); + assert_eq!(err.sqlite_error_code(), Some(crate::ErrorCode::ApiMisuse)); + assert_eq!( + err.to_string(), + "bad parameter or other API misuse".to_owned() + ); stmt.reset()?; // SQLITE_OMIT_AUTORESET = false stmt.execute([]).unwrap_err(); Ok(()) From 530292d873defabd09aa021b2ac6065d4d642d9f Mon Sep 17 00:00:00 2001 From: gwenn Date: Sat, 7 Dec 2024 09:43:52 +0100 Subject: [PATCH 2/3] Use a default error message instead --- src/error.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/error.rs b/src/error.rs index f5b4e28..38ca8b7 100644 --- a/src/error.rs +++ b/src/error.rs @@ -130,7 +130,7 @@ pub enum Error { /// error code error: ffi::Error, /// error message - msg: Option, + msg: String, /// SQL input sql: String, /// byte offset of the start of invalid token @@ -324,7 +324,7 @@ impl fmt::Display for Error { offset, ref sql, .. - } => write!(f, "{msg:?} in {sql} at offset {offset}"), + } => write!(f, "{msg} in {sql} at offset {offset}"), #[cfg(feature = "loadable_extension")] Self::InitError(ref err) => err.fmt(f), #[cfg(feature = "modern_sqlite")] @@ -457,7 +457,7 @@ pub unsafe fn error_with_offset(db: *mut ffi::sqlite3, code: c_int, sql: &str) - if offset >= 0 { return Error::SqlInputError { error, - msg, + msg: msg.unwrap_or("error".to_owned()), sql: sql.to_owned(), offset, }; From 37c50d3f98f242dd2c96a72723b957986ec880ec Mon Sep 17 00:00:00 2001 From: gwenn Date: Sat, 7 Dec 2024 10:54:07 +0100 Subject: [PATCH 3/3] Try to fix CI error with sqlcipher --- src/statement.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/statement.rs b/src/statement.rs index 02cf72e..df4cbb6 100644 --- a/src/statement.rs +++ b/src/statement.rs @@ -1288,10 +1288,8 @@ mod test { stmt.parameter_index("test")?; let err = stmt.step().unwrap_err(); assert_eq!(err.sqlite_error_code(), Some(crate::ErrorCode::ApiMisuse)); - assert_eq!( - err.to_string(), - "bad parameter or other API misuse".to_owned() - ); + // error msg is different with sqlcipher, so we use assert_ne: + assert_ne!(err.to_string(), "not an error".to_owned()); stmt.reset()?; // SQLITE_OMIT_AUTORESET = false stmt.execute([]).unwrap_err(); Ok(())