chrisdew / protobuf

Protocol Buffers for Node.JS
http://code.google.com/p/protobuf-for-node/
Apache License 2.0
234 stars 71 forks source link

How to intercept parse error messages #10

Open TheRoSS opened 12 years ago

TheRoSS commented 12 years ago

Hi! Upon parsing incorrect protobuf message the parse method throws indescriptive error message and true error message outputs to stdout. Is there any way to intercept this message in my program?

Example: My code:

try {
    var parsed = schema[inMsgType].parse(data);
} catch(e) {
    log(e)
}

log outputs just a meaningless message:

Error: Malformed message

But stdout has a string

libprotobuf ERROR google/protobuf/message_lite.cc:123] Can't parse message of type "Message" because it is missing required fields: smth.id

In server where stdout is directed to /dev/null this message will be lost. I want to catch and pass this message to my logger. Does anyone know how to do this?

String 'Error: Malformed message' goes from here: protobuf_for_node.cc:268

success = message->ParseFromArray(...)
result = success ? type->ToJs(*message) : v8::ThrowException("Malformed message")

Code from google/protobuf/message_lite.cc:123:

GOOGLE_LOG(ERROR) << InitializationErrorMessage("parse", *message);

So i think there should be some way to catch GOOGLE_LOG messages. Has anyone solved this problem?

chrisdew commented 12 years ago

Hi, this isn't urgent for me, hopefully someone else will be able to help you with this.

PretzelUA commented 11 years ago

[ Потрібно підмінити в парсера клас для виводу помилок ] Rewrite the error collector i.e.

TextFormat::Parser parser;
ProtobufLogCollector error_collector;
parser.RecordErrorsTo(&error_collector);
bool ret = parser.ParseFromString(some_string, &result_data);
if(!ret)
    // Failed to parse data update file
    return -1;

[ де ProtobufLogCollector виглядатиме наступним чином ] where

class ProtobufLogCollector : public google::protobuf::io::ErrorCollector {
    public:
        ProtobufLogCollector() {}
        ~ProtobufLogCollector() {}

        void AddError(int line, int column, const string& message) { std::cout << message << std::endl; }
        void AddWarning(int line, int column, const string& message) { std::cout << message << std::endl; }
};

ErrorCollector manual: https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.io.tokenizer#ErrorCollector

[ Звісно, замість std::cout << message << std::endl; повідомлення треба слати в свій лог чи в топку :-) ] Certainly you'll need to replace std::cout << message << std::endl; with writing to you log or /dev/null :-)

DonOregano commented 11 years ago

Try instantiating the class ::google::protobuf::LogSilencer. While there is an instance of it no logs will be made, as far as I understand. From common.h:

// Create a LogSilencer if you want to temporarily suppress all log // messages. As long as any LogSilencer objects exist, non-fatal // log messages will be discarded (the current LogHandler will not // be called). Constructing a LogSilencer is thread-safe. You may // accidentally suppress log messages occurring in another thread, but // since messages are generally for debugging purposes only, this isn't // a big deal. If you want to intercept log messages, use SetLogHandler().

ghost commented 10 years ago

@chrisdew Someone is trying to crash my Node.js server by sending malformed messages. Can you implement something to catch the errors? Thanks :)

chrisdew commented 10 years ago

I'm away on holiday for a couple of weeks. I'll have a look at your request when I return.