Programming/기타

[Google Protocol Buffer] Exception 확인 및 처리

쌍쌍바나나 2016. 5. 20. 22:00
반응형

logfile.ParseFromString(f.read())하는 과정에서 오류가 발생했다. 

오류 내용은

DecodeError: Unexpected end-group tag.

Unexpected end-group tag.


gogole.external.protobuf/internal/decoder.py의 내용을 보면 아래와 같다.


def DecodeRepeatedField(buffer, pos, end, message, field_dict):
      value = field_dict.get(key)
      if value is None:
        value = field_dict.setdefault(key, new_default(message))
      while 1:
        value = field_dict.get(key)
        if value is None:
          value = field_dict.setdefault(key, new_default(message))
        # Read length.
        (size, pos) = local_DecodeVarint(buffer, pos)
        new_pos = pos + size
        if new_pos > end:
          raise _DecodeError('Truncated message.')
        # Read sub-message.
        if value.add()._InternalParse(buffer, pos, new_pos) != new_pos:
          # The only reason _InternalParse would return early is if it
          # encountered an end-group tag.
          raise _DecodeError('Unexpected end-group tag.')
        # Predict that the next tag is another copy of the same repeated field.
        pos = new_pos + tag_len
        if buffer[new_pos:pos] != tag_bytes or new_pos == end:
          # Prediction failed.  Return.
          return new_pos
    return DecodeRepeatedField



주석을 살펴보면 

The only reason _InternalParse would return early is if it encountered an end-group tag.

repeated에서 내부에 있는 end-group tag가 먼저 리턴이 되기 때문에 발생하는 예외라고 하는데 음...

이게 무슨말인지.


google/protobuf/internal/python_message.py

_InternalParse()의 내용을 확인해보면


def InternalParse(self, buffer, pos, end):
    self._Modified()
    field_dict = self._fields
    unknown_field_list = self._unknown_fields
    while pos != end:
      (tag_bytes, new_pos) = local_ReadTag(buffer, pos)
      field_decoder, field_desc = decoders_by_tag.get(tag_bytes, (None, None))
      if field_decoder is None:
        value_start_pos = new_pos
        new_pos = local_SkipField(buffer, new_pos, end, tag_bytes)
        if new_pos == -1: # HERE I HAVE -1 !!!
          return pos
        if not unknown_field_list:
          unknown_field_list = self._unknown_fields = []
        unknown_field_list.append((tag_bytes, buffer[value_start_pos:new_pos]))
        pos = new_pos
      else:
        pos = field_decoder(buffer, new_pos, end, self, field_dict)
        if field_desc:
          self._UpdateOneofState(field_desc)
    return pos
  cls._InternalParse = InternalParse


 


그렇다면.. 일단 임시 방편으로라도

exception을 처리할 수 밖에 없다. 


 try:
     logfile = LogDataProto.LogDataFile()
     logfile.ParseFromString(f.read())
except (Exception) as detail:
     print type(detail)
     print detail  


반응형