chris from local group
chris from local group

Reputation: 357

Validation and exception vs. error message tuple

I am working on a validation function. I understand that exceptions are used for errors and unexpected situations, but in the case of a validation function, if a condition is not met inside, I would expect it to return False instead of an exception.

The thing is that after the validation finishes I need to raise an message window with a message like: "Tool exited because X condition not met". My workflow has been to return tuples with the result and message:

(True, Y_message)

or (False, X_condition_not_met)

and then:

a, b = result
if not a:
    raise_window(message=b)

However recently I have stumbled upon multiple answers raising a controversy about this issue and I am confused. For example some people say to always go with exceptions: What's the best way to return multiple values from a function in Python? and others say tuples are the way to go Best practice in python for return value on error vs. success.

I would appreciate if someone could point me in the right direction.

Upvotes: 2

Views: 3217

Answers (2)

Martijn Pieters
Martijn Pieters

Reputation: 1124070

When validating, the purpose of your function is to tell you if the criteria are met. You expect to get a boolean result; valid or not valid. You'd only throw errors if, say, the inputs to the function are not supported, or some dependency for the validation process itself was not met. In that case, the normal operation of the validator cannot be completed, you cannot return valid or not valid in such cases because there is no way for the validator to make that determination.

You can compare this with isinstance() or issubclass(); these two functions test a value against another value. They return True or False, and raise exceptions if you give them unsupported input:

>>> isinstance(1, int)
True
>>> isinstance(1, 'foobar')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: isinstance() arg 2 must be a class, type, or tuple of classes and types

Normal operation is validation, giving it unsupported input means no valid or invalid value can be returned and thus warrants an exception.

So, for a validator that returns either a (True, message) or a (False, message) tuple, I'd only raise exceptions if there was a problem with the validation process itself, not to indicate the (False, message) case.

Note that it doesn't matter what your validator returns; if you need to return both a valid / invalid flag and corresponding message (and only the validator can produce that message) then returning a tuple is just fine.

You could return a custom class too:

class ValidationResult(object):
    def __init__(self, result, message=''):
        self.result = bool(result)
        self.message = message

    def __nonzero__(self):  # Python 2
        return self.result

    __bool__ = __nonzero__  # Python 3

    def __str__(self):
        return self.message

then use that as a test:

valid = validation(value)
if not valid:
    raise_window(message=str(valid))

Upvotes: 10

Alex Gaynor
Alex Gaynor

Reputation: 15019

Using an exception to indicate invalid data is the idiomatic, canonical, Python solution to this problem. Consider the int() function, if you pass it invalid data, an exception occurs:

>>>> int('abc')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 'abc'

Upvotes: -2

Related Questions