Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get more details about errors generated during protobuf parsing? (C++)

I am new to protobuf (C++) and my code fails during parse of my messages. How can I get more details about the errors that occurred?

Example

The following snippet illustrates the problem:

const bool ok=my_message.ParseFromCodedStream(&stream);
if(ok){
    std::cout<< "message parsed. evidence:\n"<< my_message.DebugString();
}
else{
    std::cerr<< "error parsing protobuf\n";
    //HOW CAN I GET A REASON FOR THE FAILURE HERE?
}
like image 386
Lennart Rolland Avatar asked Mar 01 '14 23:03

Lennart Rolland


1 Answers

If you look inside protobuf code, you will find it's using its own logging system - based on macros. By default all these messages goes to stderr, but you can capture them in your program with SetLogHandler():

typedef void LogHandler(LogLevel level, const char* filename, int line,
                        const std::string& message);

The possible solution is to make your own errno-like mechanism (sorry for C++11-ishness):

typedef LogMessage std::tuple<LogLevel, std::string, int, std::string>;  // C++11
typedef LogStack std::list<LogMessage>;

namespace {

LogStack stack;
bool my_errno;

}  // namespace

void MyLogHandler(LogLevel level, const char* filename, int line,
                  const std::string& message) {
  stack.push_back({level, filename, line, message});  // C++11.
  my_errno = true;
}

protobuf::SetLogHandler(MyLogHandler);

bool GetError(LogStack* my_stack) {
  if (my_errno && my_stack) {
    // Dump collected logs.
    my_stack->assign(stack.begin(), stack.end());
  }

  stack.clear();
  bool old_errno = my_errno;
  my_errno = false;

  return old_errno;
}

And use it in your code:

...
else {
    std::cerr<< "error parsing protobuf" << std::endl;
    LogStack my_stack;
    if (GetError(&my_stack) {
      // Handle your errors here.
    }
}

The main drawback of my sample code - it doesn't work well with multiple threads. But that can be fixed on your own.

like image 188
abyss.7 Avatar answered Sep 22 '22 04:09

abyss.7