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

Popular posts from this blog

networking - Vagrant-provisioned VirtualBox VM is not reachable from Ubuntu host -

c# - ASP.NET Core - There is already an object named 'AspNetRoles' in the database -

ruby on rails - ArgumentError: Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true -