Search code examples
pythonbotsirc

Python: IRC bot crashes when only prefix is sent


I have an IRC bot that crashes when I only send the prefix (!)

I understand why it's happening, but I can't figure out how to make it ignore it instead of killing it.

Source: https://github.com/SamWilber/rollbot/blob/master/rollbot.py

Error:

:turtlemansam!~turtleman@unaffiliated/turtlemansam PRIVMSG #tagprobots :!
Traceback (most recent call last):
line 408, in <module>
    bot.connect()
line 81, in connect
    self.run_loop()
line 117, in run_loop
    self.handle_message(source_nick, message_dict['destination'], message_dict['message'])
in handle_message
    self.handle_command(source, destination, message)
line 139, in handle_command
    command_key = split_message[0].lower()
IndexError: list index out of range

Solution

  • The culprit is that snippet:

    def handle_command(self, source, destination, message):
        split_message = message[1:].split()
        command_key = split_message[0].lower() # L139
        …
    

    and this is because when you send only the prefix, there's no "right hand side" part after the prefix. So when you try to split that RHS part that does not exists, it is equivalent of doing the following:

    >>> "".split()[0]
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    IndexError: list index out of range
    

    Not good, uh?

    So the solution is to either add exception handling at this stage:

    try:
        split_message = message[1:].split()
        command_key = split_message[0].lower()
    except IndexError:
        print("No Command")
        return
    …
    

    though, my personal preference is over checking the length of the split_message because this is not an exceptional behavior, but a possible use case scenario:

    split_message = message[1:].split()
    if len(split_message) is 0:
        print("No Command")
        return
    else:
        command_key = split_message[0].lower()
        …
    

    In python exceptions are considered to be costless (in terms of memory/processor overhead), thus their use is usually encouraged.

    Though, if my preference is over not using an exception for this situation, it's because:

    • when you write an algorithm it is always to integrate in the execution flow the use case possibilities instead of breaking the execution flow (which is what an excption does), as it improves the readability of the code…
    • And it avoids the possibility of shadowing another exception.

    HTH