注册ErrorCollector或拦截连线格式的解析错误
register ErrorCollector or intercept parse errors for wire format?
当可以定义自定义ErrorCollector
类来处理google::protobuf
解析错误
struct ErrorCollector : ::google::protobuf::io::ErrorCollector
{
void AddError(int line, int column, const std::string& message) override
{
// log error
}
void AddWarning(int line, int column, const std::string& message) override
{
// log warning
}
};
在解析文本文件时,可以使用protobuf TextFormat
类并注册自定义ErrorCollector
::google::protobuf::io::IstreamInputStream input_stream(&file);
::google::protobuf::TextFormat::Parser parser;
ErrorCollector error_collector;
parser.RecordErrorsTo(&error_collector);
if (parser.Parse(&input_stream, &msg))
{
// handle msg
}
解析有线格式,我目前使用Message::ParseFromArray
if (msg.ParseFromArray(data, data_len))
{
// handle msg
}
这并不允许我指定一个自定义的ErrorCollector
。
我已经搜索了源代码,但到目前为止还无法找到这是否可能。
- 是否可以使用
ErrorCollector
解析线格式? - 是否有另一种方法来拦截解析错误并使其可用于客户端代码?
基本上有两种方式会导致连线格式解析失败:
- 字节不是有效的protobuf(例如,它们被损坏,或以完全不同的格式)。
- 缺少一个必填字段。
对于情形1,protobuf除了"it's invalid"之外不会给你更多的信息。这部分是为了代码的简单性(和速度),但也部分是因为任何提供更多信息的尝试通常都是误导而不是帮助。详细的错误报告对文本格式很有用,因为文本通常是由人类编写的,但机器会产生非常不同的错误。在某些语言中,protobuf实际上会报告特定的错误,比如"end-group标签不匹配start-group标签"。在绝大多数情况下,这个错误实际上只是意味着"字节损坏",但不可避免地,人们认为这个错误试图告诉他们一些他们不理解的更深层次的东西。然后,他们会向堆栈溢出提出问题,比如"我如何确保起始组和结束组标签匹配?",而实际上他们应该比较源和目的地之间的字节数,以缩小它们被损坏的地方。甚至报告发生解析错误的字节位置也不是很有用:protobuf是一种密集编码,这意味着许多随机损坏的字节序列将被解析成功,这意味着解析器可能只会在稍后的某个地方注意到问题,而不是在实际出错的地方。
有一种情况显然是可以用来区分的,那就是情况2(缺少必填字段)——至少,如果您使用了必填字段(我个人建议避免使用它们)。这里有几个选项:
- 通常,必需的字段检查将错误写入控制台(在stderr上)。你可以拦截这些并使用
SetLogHandler
以你自己的方式记录它们,但这不会给你结构化的信息,只有文本信息。 - 要更程序化地检查必填字段,可以将必填字段检查与解析分开。使用
MessageLite::ParsePartialFromArray()
或其他Partial
解析方法之一来解析消息,同时忽略必要字段的缺失。然后可以使用MessageLite::IsInitialized()
检查是否设置了所有必需的字段。如果返回false,则使用Message::FindInitializationErrors()
获取所有缺失的必填字段的路径列表。
- 如何将strftime中的格式错误作为异常捕获
- CuDNN 减少格式错误
- 漂亮的计数器习语的错误或格式错误的静态订单惨败?
- GCC 编译器是否应该对涉及 [[fallthrough]] 属性的格式错误的C++代码进行诊断?
- 在.NET Core 3.1中运行托管C++/CLI程序集时,映像格式错误
- -bash:/a.out:无法执行二进制文件:Exec格式错误
- 如何避免浮点格式错误
- 'fopen'返回格式错误的'fp'
- bash:./main:无法执行二进制文件:Exec格式错误
- 包含格式错误的模板成员函数的格式正确的程序?
- CPPRestSDK(casablanca)从传入的WebSocket消息中提取JSON(格式错误的令牌)
- 未定义的行为和格式错误之间的区别,不需要诊断消息
- C++计算中的格式错误
- C++输出格式错误
- 未知像素格式错误SDL2
- 常量的预处理器宏-格式错误
- BeautifulSoup的C / CPP版本,特别是在处理格式错误的HTML方面
- 格式错误的隐式转换示例
- bash:即使二进制和Linux是64位的,也无法执行二进制文件:Exec格式错误
- 升级后出现libcurl格式错误的url错误(CURLE_url_MALFORMAT)