2

I wonder is if throwing exceptions is the best way to communicate something to the user, in case the user is another programmer.

I'm developing a small library to create text-based games (think Dwarf Fortress, but extremely more simple). Of course, I want stuff to move inside the map. It's very simple and the docstring is very complete, so it should read nicely.

def move(self, tile):
    """Move the object to a tile.
    That means: unlink the piece from its current tile and link it
    to the new tile.

    Raise CharacterIsNotOnATileError if piece didn't already
    have an associated tile, CharacterIsNotOnThisBoardError if
    the destinity tile is not on the same board as the current tile,
    OutOfBoard error if destinity tile is falsey (most probably
    this means you're tring to move somewhere outside the map)
    """
    if tile.piece is not None:
        raise PositionOccupiedError(tile)
    if not self.home_tile:
        raise PieceIsNotOnATileError
    if self.home_tile.board is not tile.board:
        raise PieceIsNotOnThisBoardError
    if not tile:
        raise OutOfBoardError

    self.home_tile.piece = None
    tile.piece = self

Is this structure bad? I think it reads nicely: when the user tries to move a piece of his own, he can do:

try:
    character.move(somewhere)
except PositionOcuppiedError:
    character.punish  # cause i'm in hardcore
except OutOfBoardError:
    character.kill  # cause we were in a floating world and the
                    # character just fell off

There's some more logic in the library implemented like this, where the code tries to do something but if it can't, it will throw an exception. Is this OK? Or maybe I should be returning error codes (as integers, for example).

joaquinlpereyra
  • 956
  • 7
  • 17

2 Answers2

3

This usage case seems to be all right for exceptions. Some people say that:

"Exceptions should be exceptional"

but in Python, use of exceptions to perform flow control is not regarded as a bad practice (read more "Is it a good practice to use try except else in python").

Moreover, be aware that throwing and checking exceptions in Python might have a negative performance impact, if placed in repeatedly invoked functions. Unless you are developing a fast-paced game with hundreds of players, it shouldn't be your primary concern. You can read more about performance related issues of catching exceptions in this topic on Stack Overflow.

Personally, as a programmer I would rather deal with exceptions (when programming in Python) than with error codes or something similar. On the other hand, it is not much harder to to handle wide range of returned statuses if they are given as error codes - you can still mimic switch-case construct, using e.g. dictionary with callable handlers as values.

Community
  • 1
  • 1
krassowski
  • 13,598
  • 4
  • 60
  • 92
2

In my opinion throwing exceptions are better way to inform that some error occurred. Especially if your function does not return any value. Imagine that developer after each call have to check type of returned value. It is much clearer. Check this.

abdulafaja
  • 41
  • 1
  • "Imagine that developer after each call have to check type of returned value." There are a lot of languages where this is the case, and it isn't nearly as troublesome as you think. [Some would argue it's even better than exceptions.](http://www.joelonsoftware.com/items/2003/10/13.html) – Vincent Savard Aug 09 '16 at 12:55
  • As @VincentSavard argues, this is not such a straightforward answer. The article linked is interesting, but refers much to C++/Java. I think Python is way more lax with these things, but then again I'm the asker. – joaquinlpereyra Aug 09 '16 at 13:23
  • I believe raising exceptions is valid flow control in python. For example, if you are implementing your own iterable object you indicate the end of the range by raising a `StopIteration` exception. – shwoop Aug 09 '16 at 13:36