wking
wking

Reputation: 1353

catch exception in sqlite3pp

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

Answers (4)

meg18019
meg18019

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

iwongu
iwongu

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

Raydel Miranda
Raydel Miranda

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

Mr.Yellow
Mr.Yellow

Reputation: 198

I would try to catch the exception type of the message ...

catch (sqlite3pp::database_error& ex) { ... }

Upvotes: 0

Related Questions