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 <string>
#include <sstream>
#include <sqlite3.h>
namespace SQLite
@ -30,9 +32,38 @@ public:
* @param[in] aErrorMessage The string message describing the SQLite error
*/
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)
{
throw SQLite::Exception(sqlite3_errstr(aRet));
throw SQLite::Exception(mStmtPtr, aRet);
}
}

View File

@ -227,7 +227,7 @@ int Statement::exec()
{
mbOk = false;
mbDone = false;
throw SQLite::Exception(sqlite3_errstr(ret));
throw SQLite::Exception(mStmtPtr, ret);
}
}
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);
if (SQLITE_OK != ret)
{
throw SQLite::Exception(sqlite3_errstr(ret));
throw SQLite::Exception(apSQLite, ret);
}
// Initialize the reference counter of the sqlite3_stmt :
// used to share the mStmtPtr between Statement and Column objects;