Protocol Buffers C ++中的异常处理

时间:2015-04-15 02:28:01

标签: c++ exception exception-handling protocol-buffers

我没有在Protocol Buffers文档中找到任何用于C ++中的异常处理的内容。在Javadoc中,它明确定义了InvalidProtocolBufferException,但没有在C ++中定义。

有时候我运行我的程序,当它在它认为有效的消息中找到缺少的字段时崩溃,然后它就会停止并抛出这样的错误:

[libprotobuf FATAL google/protobuf/message_lite.cc:273] CHECK failed: 
IsInitialized(): Can't serialize message of type "XXX" because it is 
missing required fields: YY, ZZ
unknown file: Failure
C++ exception with description "CHECK failed: IsInitialized(): Can't 
serialize message of type "XXX" because it is missing required fields: 
YY, ZZ" thrown in the test body.

message_lite.cc的source code全部包含“GOOGLE_DCHECK”或“InitializationErrorMessage”......

我的应用程序不允许这样的异常停止程序(不确定C ++中的术语是什么,但基本上没有UncheckedExceptions),所以我真的需要一种方法来捕获这些,记录错误,并优雅地返回,以防一些消息严重损坏。无论如何这样做?为什么我看到this post表示某种google::protobuf::FatalException,但我找不到它周围的文档(只有FatalException可能还不够)。

谢谢!

2 个答案:

答案 0 :(得分:8)

您看到的失败表明您的程序中存在错误 - 程序已请求序列化邮件,而不是先填写所有必填字段。把它想象成一个分段错误。您不应该尝试捕获此异常 - 您应该修改您的应用程序,以便从一开始就不会发生异常。

请注意,检查是DCHECK,这意味着它只在调试版本中检查。在发布版本中(定义{{​​1}}时),将跳过此检查,即使消息无效,也会写入消息。因此,只有在调试时,您才不必担心这会使您的应用程序在生产中崩溃。

(从技术上讲,你可以捕获NDEBUG,但Protobuf代码原本并不是设计为异常安全的。最初,检查失败只会中止程序。看起来最近添加了google::protobuf::FatalException,但由于代码不是异常安全的,因此在FatalException被抛出的任何时候都可能会出现内存泄漏。所以,您可能应该像FatalException那样对待它。)

答案 1 :(得分:0)

我解决了 我的问题和你一样。 如果在您进行序列化时另一个线程更改了原型项的大小,则抛出 FatalException 然后我首先将其复制到另一个原型项目中,然后将其序列化。

            ProtoInput item; // it is global object
            . 
            .
            .
            fstream output("myfile",
                    ios::out | ios::trunc | ios::binary);

            ProtoInput in;
            in.CopyFrom(item);
            size_t size = in.ByteSizeLong();
            void *buffer = malloc(size);
            if (in.SerializeToArray(buffer, size) == true) {
                output.write((char *) buffer, size);
            }
            output.close();
            free(buffer);