From 94ebe5ced6eb536499819a0d1a3bb63add33bc32 Mon Sep 17 00:00:00 2001 From: fekir Date: Sat, 19 Aug 2017 08:53:01 +0200 Subject: [PATCH 1/4] Add default copy constructor to exception class The throw statement may copy the exception, since exception are thrown by value Having const members disables the assignment operator --- CMakeLists.txt | 1 + include/SQLiteCpp/Exception.h | 4 ++-- tests/Exception_test.cpp | 44 +++++++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 tests/Exception_test.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index bf1fcbb..4a3e492 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -134,6 +134,7 @@ set(SQLITECPP_TESTS tests/Backup_test.cpp tests/Transaction_test.cpp tests/VariadicBind_test.cpp + tests/Exception_test.cpp ) source_group(tests FILES ${SQLITECPP_TESTS}) diff --git a/include/SQLiteCpp/Exception.h b/include/SQLiteCpp/Exception.h index b064ad9..3b0b772 100644 --- a/include/SQLiteCpp/Exception.h +++ b/include/SQLiteCpp/Exception.h @@ -91,8 +91,8 @@ public: const char* getErrorStr() const noexcept; // nothrow private: - const int mErrcode; ///< Error code value - const int mExtendedErrcode; ///< Detailed error code if any + int mErrcode; ///< Error code value + int mExtendedErrcode; ///< Detailed error code if any }; diff --git a/tests/Exception_test.cpp b/tests/Exception_test.cpp new file mode 100644 index 0000000..621c9c8 --- /dev/null +++ b/tests/Exception_test.cpp @@ -0,0 +1,44 @@ +/** + * @file Transaction_test.cpp + * @ingroup tests + * @brief Test of a SQLite Transaction. + * + * Copyright (c) 2012-2016 Sebastien Rombauts (sebastien.rombauts@gmail.com) + * + * Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt + * or copy at http://opensource.org/licenses/MIT) + */ + +#include + +#include + +TEST(Exception, copy) { + const SQLite::Exception ex1("some error", 2); + const SQLite::Exception ex2 = ex1; + EXPECT_STREQ(ex1.what(), ex2.what()); + EXPECT_EQ(ex1.getErrorCode(), ex2.getErrorCode()); + EXPECT_EQ(ex1.getExtendedErrorCode(), ex2.getExtendedErrorCode()); +} + +// see http://eel.is/c++draft/exception#2 or http://www.cplusplus.com/reference/exception/exception/operator=/ +// an assignment operator is expected to be avaiable +TEST(Exception, assignment) { + const SQLite::Exception ex1("some error", 2); + SQLite::Exception ex2("some error2", 3); + + ex2 = ex1; + + EXPECT_STREQ(ex1.what(), ex2.what()); + EXPECT_EQ(ex1.getErrorCode(), ex2.getErrorCode()); + EXPECT_EQ(ex1.getExtendedErrorCode(), ex2.getExtendedErrorCode()); +} + +TEST(Exception, throw_catch) { + const char message[] = "some error"; + try { + throw SQLite::Exception(message); + } catch (const std::runtime_error& ex) { + EXPECT_STREQ(ex.what(), message); + } +} From 67ac88fb1eec6679219cfb19ef0e489a229b8346 Mon Sep 17 00:00:00 2001 From: fekir Date: Sat, 19 Aug 2017 08:59:57 +0200 Subject: [PATCH 2/4] Add SQLite::Exception constructor that takes const char* in order to avoid possible std::bad_alloc exception std::runtime_error provides such overload in c++11, therefore it will make no difference when compiling for c++03, but should provide no harm either --- include/SQLiteCpp/Exception.h | 2 ++ src/Exception.cpp | 13 +++++++++++++ 2 files changed, 15 insertions(+) diff --git a/include/SQLiteCpp/Exception.h b/include/SQLiteCpp/Exception.h index 3b0b772..efc9fb5 100644 --- a/include/SQLiteCpp/Exception.h +++ b/include/SQLiteCpp/Exception.h @@ -50,6 +50,7 @@ public: * * @param[in] aErrorMessage The string message describing the SQLite error */ + explicit Exception(const char* aErrorMessage); explicit Exception(const std::string& aErrorMessage); /** @@ -58,6 +59,7 @@ public: * @param[in] aErrorMessage The string message describing the SQLite error * @param[in] ret Return value from function call that failed. */ + Exception(const char* aErrorMessage, int ret); Exception(const std::string& aErrorMessage, int ret); /** diff --git a/src/Exception.cpp b/src/Exception.cpp index c2f0304..69e114e 100644 --- a/src/Exception.cpp +++ b/src/Exception.cpp @@ -16,6 +16,12 @@ namespace SQLite { +Exception::Exception(const char* aErrorMessage) : + std::runtime_error(aErrorMessage), + mErrcode(-1), // 0 would be SQLITE_OK, which doesn't make sense + mExtendedErrcode(-1) +{ +} Exception::Exception(const std::string& aErrorMessage) : std::runtime_error(aErrorMessage), mErrcode(-1), // 0 would be SQLITE_OK, which doesn't make sense @@ -23,6 +29,13 @@ Exception::Exception(const std::string& aErrorMessage) : { } +Exception::Exception(const char* aErrorMessage, int ret) : + std::runtime_error(aErrorMessage), + mErrcode(ret), + mExtendedErrcode(-1) +{ +} + Exception::Exception(const std::string& aErrorMessage, int ret) : std::runtime_error(aErrorMessage), mErrcode(ret), From b2f059e188b9dd5c0b0b7618fb2a8417abbd6c6a Mon Sep 17 00:00:00 2001 From: fekir Date: Sat, 19 Aug 2017 09:18:28 +0200 Subject: [PATCH 3/4] Add test for constructor consistency --- tests/Exception_test.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/Exception_test.cpp b/tests/Exception_test.cpp index 621c9c8..9a71c10 100644 --- a/tests/Exception_test.cpp +++ b/tests/Exception_test.cpp @@ -13,6 +13,8 @@ #include +#include + TEST(Exception, copy) { const SQLite::Exception ex1("some error", 2); const SQLite::Exception ex2 = ex1; @@ -42,3 +44,19 @@ TEST(Exception, throw_catch) { EXPECT_STREQ(ex.what(), message); } } + + +TEST(Exception, constructor) { + const char msg1[] = "error msg"; + std::string msg2 = msg1; + { + const SQLite::Exception ex1(msg1); + const SQLite::Exception ex2(msg2); + EXPECT_STREQ(ex1.what(), ex2.what()); + } + { + const SQLite::Exception ex1(msg1, 1); + const SQLite::Exception ex2(msg2, 1); + EXPECT_STREQ(ex1.what(), ex2.what()); + } +} From a826dcacc11148a2d0a8c809418e57c6126f745c Mon Sep 17 00:00:00 2001 From: fekir Date: Sat, 19 Aug 2017 09:19:55 +0200 Subject: [PATCH 4/4] Improve test for constructor consistency --- tests/Exception_test.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/Exception_test.cpp b/tests/Exception_test.cpp index 9a71c10..d2c1ef8 100644 --- a/tests/Exception_test.cpp +++ b/tests/Exception_test.cpp @@ -53,10 +53,14 @@ TEST(Exception, constructor) { const SQLite::Exception ex1(msg1); const SQLite::Exception ex2(msg2); EXPECT_STREQ(ex1.what(), ex2.what()); + EXPECT_EQ(ex1.getErrorCode(), ex2.getErrorCode()); + EXPECT_EQ(ex1.getExtendedErrorCode(), ex2.getExtendedErrorCode()); } { const SQLite::Exception ex1(msg1, 1); const SQLite::Exception ex2(msg2, 1); EXPECT_STREQ(ex1.what(), ex2.what()); + EXPECT_EQ(ex1.getErrorCode(), ex2.getErrorCode()); + EXPECT_EQ(ex1.getExtendedErrorCode(), ex2.getExtendedErrorCode()); } }