python - What's the Pythonic way to report nonfatal errors in a parser? -
a parser created reads recorded chess games file. api used this:
import chess.pgn pgn_file = open("games.pgn") first_game = chess.pgn.read_game(pgn_file) second_game = chess.pgn.read_game(pgn_file) # ...
sometimes illegal moves (or other problems) encountered. pythonic way handle them?
raising exceptions error encountered. however, makes every problem fatal, in execution stops. often, there still useful data has been parsed , returned. also, can not continue parsing next data set, because still in middle of half-read data.
accumulating exceptions , raising them @ end of game. makes error fatal again, @ least can catch , continue parsing next game.
introduce optional argument this:
game = chess.pgn.read_game(pgn_file, parser_info) if parser_info.error: # appears quite verbose. # can @ least make best of sucessfully parsed parts. # ...
are of these or other methods used in wild?
actually, are fatal errors -- @ least, far being able reproduce correct game; on other hand, maybe player did make illegal move , nobody noticed @ time (which make warning, not fatal error).
given possibility of both fatal errors (file corrupted) , warnings (an illegal move made, subsequent moves show consistency move (in other words, user error , nobody caught @ time)) recommend combination of first , second options:
- raise exception when continued parsing isn't option
- collect errors/warnings don't preclude further parsing until end
if don't encounter fatal error can return game, plus warnings/non-fatal errors, @ end:
return game, warnings, errors
but if hit fatal error?
no problem: create custom exception can attach usable portion of game , other warnings/non-fatal errors to:
raise parsingerror( 'error explanation here', game=game, warnings=warnings, errors=errors, )
then when catch error can access recoverable portion of game, along warnings , errors.
the custom error might be:
class parsingerror(exception): def __init__(self, msg, game, warnings, errors): super().__init__(msg) self.game = game self.warnings = warnings self.errors = errors
and in use:
try: first_game, warnings, errors = chess.pgn.read_game(pgn_file) except chess.pgn.parsingerror err: first_game = err.game warnings = err.warnings errors = err.errors # whatever else want handle exception
this similar how subprocess
module handles errors.
for ability retrieve , parse subsequent games after game fatal error suggest change in api:
- have game iterator returns raw data each game (it has know how tell when 1 game ends , next begins)
- have parser take raw game data , parse (so it's no longer in charge of in file happen be)
this way if have five-game file , game 2 dies, can still attempt parse games 3, 4, , 5.
Comments
Post a Comment