Reputation: 1353
I'm using sqlite3pp to manipulate database. When I tried to insert one record twice in the same table by running,
sqlite3pp::command cmd(db, "INSERT INTO Groups (Name) VALUES (?)");
cmd.binder() << "Group_one";
cmd.execute();
it throwed an excpetion and showed me this:
libc++abi.dylib: terminating with uncaught exception of type sqlite3pp::database_error: UNIQUE constraint failed: Groups.Name
But I'm not sure what type of exception should I use to catch? I tried
try {
cmd.execute();
} catch (std::exception& ex) {}
or
try {
cmd.execute();
} catch (sqlite3pp::database_error& ex) {}
or
try {
cmd.execute();
} catch (...) {}
But none of them work. Can anyone help me here? Thanks!
Here is my code:
#include <iostream>
#include "sqlite3pp.h"
int main(int argc, const char * argv[]) {
sqlite3pp::database db("./test.db");
// Create table
db.execute("CREATE TABLE IF NOT EXISTS Groups(" \
"Name TEXT PRIMARY KEY)");
sqlite3pp::command cmd(db, "INSERT INTO Groups (Name) VALUES (?)");
cmd.binder() << "Group_one";
try {
cmd.execute(); // When I run this code twice, the exception is thrown because of UNIQUE constraint.
} catch (std::exception& ex) {
std::cout << "exception: " << ex.what() << std::endl;
}
std::cout << "Done" << std::endl;
return 0;
}
Upvotes: 1
Views: 877
Reputation: 159
I was having this same issue - could not catch the exception no matter what I tried. However, after some digging I found out that C++11 declares destructors to be noexcept by default. I am using C++11 and was able to "fix" the issue by making the following change to the sqlite3pp code:
~transaction() noexcept(false);
transaction::~transaction() noexcept(false)
So, perhaps this is the issue the OP had?
Upvotes: 0
Reputation: 401
I'm the writer of sqlite3pp and sorry for confusing you.
When I wrote this, I tried to make it very light weight. So, I decided not to translate all the sqlite3 error codes into c++ exceptions.
So, as a result, the methods have the integer type return value, which is the exact same error code that sqlite3 methods return. So, in this case, you need to check the return value of execute().
But, in some places, it cannot return the error code. e.g. in ctor and dtor. For these places, I introduced the database_error exception.
Upvotes: 1
Reputation: 14360
I've look into the code and in the tests the developers use code like this:
#include "sqlite3pp.h"
try
{
sqlite3pp::command cmd(...);
cmd.execute();
}
catch (exception& ex) { // Note they use a reference here "exception&"
cout << ex.what() << endl;
}
so, you should use the same, if that doesn't work either, try to catch all using:
try {
cmd.execute();
} catch (...) {} // Using the ... should fix the error, but I recomend you to find the correct exception you have to catch.
Looking at the code closer
I have found the class (in sqlite3pp.h):
class database_error : public std::runtime_error
{
public:
explicit database_error(char const* msg);
explicit database_error(database& db);
};
So you should solve the problem using:
try {
cmd.execute();
} catch (database_error &e) {}
Upvotes: 0
Reputation: 198
I would try to catch the exception type of the message ...
catch (sqlite3pp::database_error& ex) { ... }
Upvotes: 0