Use new Exception constructors everywhere appropriate.

Fix compiling with C++11.
Added public assessor methods to Exception class.
Added more Exception constructors as needed.
This commit is contained in:
Douglas Heriot 2016-05-26 12:34:14 +10:00
parent 832e89440f
commit 2cd31179f4
5 changed files with 95 additions and 62 deletions

View File

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

View File

@ -16,60 +16,6 @@
#include <sqlite3.h>
namespace SQLite
{
/**
* @brief Encapsulation of the error message from SQLite3, based on std::runtime_error.
*/
class Exception : public std::runtime_error
{
public:
/**
* @brief Encapsulation of the error message from SQLite3, based on std::runtime_error.
*
* @param[in] aErrorMessage The string message describing the SQLite error
*/
explicit Exception(const std::string& 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;
};
} // namespace SQLite
/// Compatibility with non-clang compilers.
#ifndef __has_feature
#define __has_feature(x) 0
@ -87,3 +33,91 @@ public:
// Visual Studio 2013 does not support noexcept, and "throw()" is deprecated by C++11
#define noexcept
#endif
namespace SQLite
{
/**
* @brief Encapsulation of the error message from SQLite3, based on std::runtime_error.
*/
class Exception : public std::runtime_error
{
public:
/**
* @brief Encapsulation of the error message from SQLite3, based on std::runtime_error.
*
* @param[in] aErrorMessage The string message describing the SQLite error
*/
explicit Exception(const std::string& aErrorMessage) :
std::runtime_error(aErrorMessage),
mErrcode(-1), // 0 would be SQLITE_OK, which doesn't make sense
mExtendedErrcode(-1)
{
}
/**
* @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.
*/
explicit Exception(sqlite3* apSQLite) :
std::runtime_error(sqlite3_errmsg(apSQLite)),
mErrcode(sqlite3_errcode(apSQLite)),
mExtendedErrcode(sqlite3_extended_errcode(apSQLite))
{
}
/**
* @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) :
std::runtime_error(sqlite3_errmsg(apSQLite)),
mErrcode(ret),
mExtendedErrcode(sqlite3_extended_errcode(apSQLite))
{
}
/**
* @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.
* @param[in] aErrorMessage String providing more context, added to the SQLite errmsg
*/
explicit Exception(sqlite3* apSQLite, int ret, const std::string &aErrorMessage) :
std::runtime_error(aErrorMessage + ": " + sqlite3_errmsg(apSQLite)),
mErrcode(ret),
mExtendedErrcode(sqlite3_extended_errcode(apSQLite))
{
}
/// @brief Return the result code (if any, otherwise -1).
inline int getErrorCode() const noexcept // nothrow
{
return mErrcode;
}
/// @brief Return the extended numeric result code (if any, otherwise -1).
inline int getExtendedErrorCode() const noexcept // nothrow
{
return mExtendedErrcode;
}
/// @brief Return a string, solely based on the error code
inline const char *getErrStr() const noexcept // nothrow
{
return sqlite3_errstr(mErrcode);
}
private:
const int mErrcode;
const int mExtendedErrcode;
};
} // namespace SQLite

View File

@ -31,8 +31,7 @@ Backup::Backup(Database& aDestDatabase,
apSrcDatabaseName);
if (NULL == mpSQLiteBackup)
{
std::string strerr = sqlite3_errmsg(aDestDatabase.getHandle());
throw SQLite::Exception(strerr);
throw SQLite::Exception(aDestDatabase.getHandle());
}
}

View File

@ -36,9 +36,9 @@ Database::Database(const char* apFilename,
const int ret = sqlite3_open_v2(apFilename, &mpSQLite, aFlags, apVfs);
if (SQLITE_OK != ret)
{
std::string strerr = sqlite3_errstr(ret);
const SQLite::Exception exception(mpSQLite, ret); // must create before closing
sqlite3_close(mpSQLite); // close is required even in case of error on opening
throw SQLite::Exception(strerr);
throw exception;
}
if (aBusyTimeoutMs > 0)
@ -58,9 +58,9 @@ Database::Database(const std::string& aFilename,
const int ret = sqlite3_open_v2(aFilename.c_str(), &mpSQLite, aFlags, aVfs.empty() ? NULL : aVfs.c_str());
if (SQLITE_OK != ret)
{
std::string strerr = sqlite3_errstr(ret);
const SQLite::Exception exception(mpSQLite, ret); // must create before closing
sqlite3_close(mpSQLite); // close is required even in case of error on opening
throw SQLite::Exception(strerr);
throw exception;
}
if (aBusyTimeoutMs > 0)

View File

@ -195,7 +195,7 @@ bool Statement::executeStep()
{
mbOk = false;
mbDone = false;
throw SQLite::Exception(sqlite3_errstr(ret));
throw SQLite::Exception(mStmtPtr, ret);
}
}
else