# Buggy code
def ParseFileObject(self, parser_mediator, file_object, **kwargs):
    """Parses a text file-like object using a lexer.

    Args:
      parser_mediator: A parser mediator object (instance of ParserMediator).
      file_object: A file-like object.

    Raises:
      UnableToParseFile: when the file cannot be parsed.
    """
    file_entry = parser_mediator.GetFileEntry()
    path_spec_printable = "{0:s}:{1:s}".format(
        file_entry.path_spec.type_indicator, file_entry.name
    )

    self.file_entry = file_entry
    # TODO: this is necessary since we inherit from lexer.SelfFeederMixIn.
    self.file_object = file_object

    # Start by checking, is this a text file or not? Before we proceed
    # any further.
    file_object.seek(0, os.SEEK_SET)
    if not utils.IsText(file_object.read(40)):
        raise errors.UnableToParseFile("Not a text file, unable to proceed.")

    file_object.seek(0, os.SEEK_SET)

    error_count = 0
    file_verified = False
    # We need to clear out few values in the Lexer before continuing.
    # There might be some leftovers from previous run.
    self.error = 0
    self.buffer = ""

    while True:
        _ = self.NextToken()

        if self.state == "INITIAL":
            self.entry_offset = getattr(self, "next_entry_offset", 0)
            self.next_entry_offset = file_object.tell() - len(self.buffer)

        if not file_verified and self.error >= self.MAX_LINES * 2:
            logging.debug(
                "Lexer error count: {0:d} and current state {1:s}".format(
                    self.error, self.state
                )
            )
            raise errors.UnableToParseFile(
                "[{0:s}] unsupported file: {1:s}.".format(
                    self.NAME, path_spec_printable
                )
            )

        if self.line_ready:
            try:
                self.ParseLine(parser_mediator)
                file_verified = True

            except errors.TimestampNotCorrectlyFormed as exception:
                error_count += 1
                if file_verified:
                    logging.debug(
                        "[{0:s} VERIFIED] Error count: {1:d} and ERROR: {2:d}".format(
                            path_spec_printable, error_count, self.error
                        )
                    )
                    logging.warning(
                        "[{0:s}] Unable to parse timestamp with error: {1:s}".format(
                            self.NAME, exception
                        )
                    )

                else:
                    logging.debug(
                        (
                            "[{0:s} EVALUATING] Error count: {1:d} and ERROR: {2:d})"
                        ).format(path_spec_printable, error_count, self.error)
                    )

                    if error_count >= self.MAX_LINES:
                        raise errors.UnableToParseFile(
                            "[{0:s}] unsupported file: {1:s}.".format(
                                self.NAME, path_spec_printable
                            )
                        )

            finally:
                self.ClearValues()

        if self.Empty():
            # Try to fill the buffer to prevent the parser from ending prematurely.
            self.Feed()

        if self.Empty():
            break

    if not file_verified:
        raise errors.UnableToParseFile(
            "[{0:s}] unable to parser file: {1:s}.".format(
                self.NAME, path_spec_printable
            )
        )

    file_offset = file_object.get_offset()
    if file_offset < file_object.get_size():
        parser_mediator.ProduceParseError(
            (
                "{0:s} prematurely terminated parsing: {1:s} at offset: 0x{2:08x}."
            ).format(self.NAME, path_spec_printable, file_offset)
        )


# Traceback (UnicodeDecodeError)
Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/plaso/engine/worker.py", line 169, in _ParseFileEntryWithParser
parser_object.UpdateChainAndParse(self._parser_mediator)
File "/usr/lib/python2.7/dist-packages/plaso/parsers/interface.py", line 72, in UpdateChainAndParse
self.Parse(parser_mediator, **kwargs)
File "/usr/lib/python2.7/dist-packages/plaso/parsers/interface.py", line 256, in Parse
self.ParseFileObject(parser_mediator, file_object, **kwargs)
File "/usr/lib/python2.7/dist-packages/plaso/parsers/text_parser.py", line 160, in ParseFileObject
_ = self.NextToken()
File "/usr/lib/python2.7/dist-packages/plaso/lib/lexer.py", line 191, in NextToken
return Lexer.NextToken(self)
File "/usr/lib/python2.7/dist-packages/plaso/lib/lexer.py", line 99, in NextToken
possible_next_state = callback(string=m.group(0), match=m)
File "/usr/lib/python2.7/dist-packages/plaso/parsers/text_parser.py", line 119, in ParseIncomplete
self.attributes['body'] += match.group(0)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 0: ordinal not in range(128)

# Fixed code
def ParseFileObject(self, parser_mediator, file_object, **kwargs):
    """Parses a text file-like object using a lexer.

    Args:
      parser_mediator: a parser mediator object (instance of ParserMediator).
      file_object: a file-like object.

    Raises:
      UnableToParseFile: when the file cannot be parsed.
    """
    file_entry = parser_mediator.GetFileEntry()
    path_spec_printable = "{0:s}:{1:s}".format(
        file_entry.path_spec.type_indicator, file_entry.name
    )

    self.file_entry = file_entry
    # TODO: this is necessary since we inherit from lexer.SelfFeederMixIn.
    self.file_object = file_object

    # Start by checking, is this a text file or not? Before we proceed
    # any further.
    file_object.seek(0, os.SEEK_SET)
    if not utils.IsText(file_object.read(40)):
        raise errors.UnableToParseFile("Not a text file, unable to proceed.")

    file_object.seek(0, os.SEEK_SET)

    error_count = 0
    file_verified = False
    # We need to clear out few values in the Lexer before continuing.
    # There might be some leftovers from previous run.
    self.error = 0
    self.buffer = ""

    while True:
        _ = self.NextToken()

        if self.state == "INITIAL":
            self.entry_offset = getattr(self, "next_entry_offset", 0)
            self.next_entry_offset = file_object.tell() - len(self.buffer)

        if not file_verified and self.error >= self.MAX_LINES * 2:
            logging.debug(
                "Lexer error count: {0:d} and current state {1:s}".format(
                    self.error, self.state
                )
            )
            raise errors.UnableToParseFile(
                "[{0:s}] unsupported file: {1:s}.".format(
                    self.NAME, path_spec_printable
                )
            )

        if self.line_ready:
            try:
                self.ParseLine(parser_mediator)
                file_verified = True

            except errors.TimestampNotCorrectlyFormed as exception:
                error_count += 1
                if file_verified:
                    logging.debug(
                        "[{0:s} VERIFIED] Error count: {1:d} and ERROR: {2:d}".format(
                            path_spec_printable, error_count, self.error
                        )
                    )
                    logging.warning(
                        "[{0:s}] Unable to parse timestamp with error: {1:s}".format(
                            self.NAME, exception
                        )
                    )

                else:
                    logging.debug(
                        (
                            "[{0:s} EVALUATING] Error count: {1:d} and ERROR: {2:d})"
                        ).format(path_spec_printable, error_count, self.error)
                    )

                    if error_count >= self.MAX_LINES:
                        raise errors.UnableToParseFile(
                            "[{0:s}] unsupported file: {1:s}.".format(
                                self.NAME, path_spec_printable
                            )
                        )

            finally:
                self.ClearValues()

        if self.Empty():
            # Try to fill the buffer to prevent the parser from ending prematurely.
            self.Feed()

        if self.Empty():
            break

    if not file_verified:
        raise errors.UnableToParseFile(
            "[{0:s}] unable to parser file: {1:s}.".format(
                self.NAME, path_spec_printable
            )
        )

    file_offset = file_object.get_offset()
    if file_offset < file_object.get_size():
        parser_mediator.ProduceParseError(
            (
                "{0:s} prematurely terminated parsing: {1:s} at offset: 0x{2:08x}."
            ).format(self.NAME, path_spec_printable, file_offset)
        )