Search code examples
genie

Handling errors with Genie


I am trying to refactor a python class into Genie, but I am stuck with how to handle errors. Some pointers would be greatly appreciated.

If I understood properly, the way of handling errors with Genie is using Try...except blocks, but how to translate the following type of error handling into this paradigm:

# Enable dictionary/list-style access to options and arguments.
def __getitem__(self, key):
    if isinstance(key, int):
        if key < len(self.arguments):
            return self.arguments[key]
        else:
            raise ArgParserError(
                "positional argument index [%s] is out of bounds" % key
            )
    else:
        option = self._get_opt(key)
        return option.value

The code I am at right now looks like (in Genie):

def getitem (key:int):string
    if key.is_int()
        if key < len(_arguments)
            return _arguments[key]
        else
            raise ArgParserError(
                "positional argument index [%s] is out of bounds", key
            )
    else
        var option = _get_opt(key)
        return option.value

This is a dummy code, I am only modelling the problem and I am aware that it will not compile as is. I am only looking for a pointer on how to transate the '''raise''' command from python.


Solution

  • You need to define the error type as an exception and then identify that your getitem function raises such an error:

    exception ArgParserError
        OUT_OF_BOUNDS
    
    def getitem( key:int ):string raises ArgParserError
        if key < len(_arguments)
            return _arguments[key]
        else
            raise new ArgParserError.OUT_OF_BOUNDS(
                "positional argument index [%s] is out of bounds", key
                 )
    

    Genie is statically typed so the if key.is_int() is unnecessary. The Vala compiler will check at compile time that all calls to the getitem function pass an integer as the argument.

    An alternative approach is to use an out parameter for the result value and use the function's return value to signal if the result is valid:

    def getitem( key:uint, out value:string ):bool
        result:bool = false
        value = ""
        if key < _arguments.length
            value = _arguments[ key ]
            result = true
        else
            info( "positional argument index [%s] is out of bounds", key )
        return result
    

    By making the key an unsigned integer, uint, a negative index can't be passed. The call to info() will log some details of the out of bounds index should you need it for debugging later.