Better exception messages when statements fail

Added new constructor to Exception that takes sqlite3* pointer, allowing for getting more information out. Makes it much easier to debug syntax errors in prepared statements, for example.
This commit is contained in:
Douglas Heriot 2016-05-26 00:34:34 +10:00
parent b55f521ca4
commit 832e89440f
3 changed files with 35 additions and 4 deletions

View File

@ -12,6 +12,8 @@
#include <stdexcept> #include <stdexcept>
#include <string> #include <string>
#include <sstream>
#include <sqlite3.h>
namespace SQLite namespace SQLite
@ -30,9 +32,38 @@ public:
* @param[in] aErrorMessage The string message describing the SQLite error * @param[in] aErrorMessage The string message describing the SQLite error
*/ */
explicit Exception(const std::string& aErrorMessage) : explicit Exception(const std::string& aErrorMessage) :
std::runtime_error(aErrorMessage) std::runtime_error(aErrorMessage),
errcode(0),
extendedErrcode(0),
errstr(),
errmsg()
{ {
} }
/**
* @brief Encapsulation of the error message from SQLite3, based on std::runtime_error.
*
* @param[in] apSQLite The SQLite object, to obtain detailed error messages from.
* @param[in] ret Return value from function call that failed.
*/
explicit Exception(sqlite3* apSQLite, int ret) :
errcode(ret),
extendedErrcode(sqlite3_extended_errcode(apSQLite)),
errstr(sqlite3_errstr(ret)),
errmsg(sqlite3_errmsg(apSQLite)),
std::runtime_error([apSQLite, ret](){
std::ostringstream message;
message << sqlite3_errstr(ret) << ": " << sqlite3_errmsg(apSQLite);
return message.str();
}())
{
}
const int errcode;
const int extendedErrcode;
const std::string errstr;
const std::string errmsg;
}; };

View File

@ -457,7 +457,7 @@ private:
{ {
if (SQLITE_OK != aRet) if (SQLITE_OK != aRet)
{ {
throw SQLite::Exception(sqlite3_errstr(aRet)); throw SQLite::Exception(mStmtPtr, aRet);
} }
} }

View File

@ -227,7 +227,7 @@ int Statement::exec()
{ {
mbOk = false; mbOk = false;
mbDone = false; mbDone = false;
throw SQLite::Exception(sqlite3_errstr(ret)); throw SQLite::Exception(mStmtPtr, ret);
} }
} }
else else
@ -317,7 +317,7 @@ Statement::Ptr::Ptr(sqlite3* apSQLite, std::string& aQuery) :
const int ret = sqlite3_prepare_v2(apSQLite, aQuery.c_str(), static_cast<int>(aQuery.size()), &mpStmt, NULL); const int ret = sqlite3_prepare_v2(apSQLite, aQuery.c_str(), static_cast<int>(aQuery.size()), &mpStmt, NULL);
if (SQLITE_OK != ret) if (SQLITE_OK != ret)
{ {
throw SQLite::Exception(sqlite3_errstr(ret)); throw SQLite::Exception(apSQLite, ret);
} }
// Initialize the reference counter of the sqlite3_stmt : // Initialize the reference counter of the sqlite3_stmt :
// used to share the mStmtPtr between Statement and Column objects; // used to share the mStmtPtr between Statement and Column objects;