【问题标题】:catch exception in sqlite3pp在 sqlite3pp 中捕获异常
【发布时间】:2015-04-14 11:40:12
【问题描述】:

我正在使用sqlite3pp 来操作数据库。当我尝试通过运行在同一个表中插入一条记录两次时,

 sqlite3pp::command cmd(db, "INSERT INTO Groups (Name) VALUES (?)");
 cmd.binder() << "Group_one";
 cmd.execute();

它抛出了一个异常并向我展示了这个:

libc++abi.dylib:以未捕获的类型异常终止 sqlite3pp::database_error: UNIQUE 约束失败:Groups.Name

但我不确定我应该使用什么类型的异常来捕获?我试过了

try {
    cmd.execute();
} catch (std::exception& ex) {}

try {
    cmd.execute();
} catch (sqlite3pp::database_error& ex) {}

try {
    cmd.execute();
} catch (...) {}

但它们都不起作用。有人能帮我一下吗?谢谢!

这是我的代码:

#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;
}

【问题讨论】:

    标签: c++ exception sqlite


    【解决方案1】:

    我是 sqlite3pp 的作者,很抱歉让您感到困惑。

    当我写这篇文章时,我试图让它变得很轻。所以,我决定不把所有的 sqlite3 错误代码都翻译成 c++ 异常。

    因此,这些方法具有整数类型的返回值,这与 sqlite3 方法返回的错误代码完全相同。所以,在这种情况下,你需要检查execute()的返回值。

    但是,在某些地方,它不能返回错误代码。例如在 ctor 和 dtor 中。对于这些地方,我引入了database_error异常。

    【讨论】:

    • 感谢您的回答。现在我知道了。也许将错误代码转换为 C++ 异常会有所帮助。但这只是给我的。
    【解决方案2】:

    我会尝试捕捉消息的异常类型...

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

    【讨论】:

      【解决方案3】:

      我查看了代码,在测试中开发人员使用如下代码:

       #include "sqlite3pp.h"
       try 
       {
           sqlite3pp::command cmd(...);
           cmd.execute();
       }
       catch (exception& ex) { // Note they use a reference here "exception&"
           cout << ex.what() << endl;
       }
      

      所以,您应该使用相同的方法,如果这也不起作用,请尝试使用以下方法捕获所有内容:

      try {
          cmd.execute();
      } catch (...) {} // Using the ... should fix the error, but I recomend you to find the correct exception you have to catch.
      

      仔细查看代码

      我找到了课程(在 sqlite3pp.h 中):

       class database_error : public std::runtime_error
       {
          public:
          explicit database_error(char const* msg);
          explicit database_error(database& db);
       };
      

      所以你应该使用以下方法解决问题:

      try {
          cmd.execute();
      } catch (database_error &e) {}
      

      【讨论】:

      • 哇!!,这很奇怪。我唯一想到的是,异常是从代码中的另一个地方抛出的。
      • 我已经发布了我的代码,这很简单。但我就是想不通。
      • 可以尝试(用于测试),将所有代码放在 try-catch 块中吗?我怀疑cmd.binder() &lt;&lt; "Group_one";
      • try-catch 块中的所有代码仍然不起作用。我发现 db.execute() 不会抛出异常,但它没有帮助,因为我需要捕获异常才能知道新记录是否插入成功。
      【解决方案4】:

      我遇到了同样的问题 - 无论我尝试什么都无法捕获异常。但是,经过一番挖掘,我发现 C++11 默认将析构函数声明为 noexcept 。我正在使用 C++11,并且能够通过对 sqlite3pp 代码进行以下更改来“修复”该问题:

      ~transaction() noexcept(false);
      transaction::~transaction() noexcept(false)
      

      那么,也许这就是 OP 的问题?

      【讨论】:

        猜你喜欢
        • 2010-10-03
        • 2012-07-10
        • 1970-01-01
        • 2011-05-29
        • 2011-07-02
        • 2021-08-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多