error handler in a testcase verification helper

Viewed 30

Having a verification helper function (which would be called by various testcases with different boolean values passed for raise_on_error):

def verify_multiply(a: int, b: int, c: int, raise_on_error=True):
    if a * b == c:
        return True
    else:
        error_msg = f"{a} * {b} != {c}"
        if raise_on_error:
            raise ValueError(error_msg)
        else:
            log.error(error_msg)
            return False

I wanted to replace the error handler with a wrapper like:

def error_handler(error_msg, raise_on_error=True):
    if raise_on_error:
        raise ValueError(error_msg)
    else:
        log.error(error_msg)
        return False

So that the original verifier could be written into:

def verify_multiply(a: int, b: int, c: int, raise_on_error=True):
    if a * b == c:
        return True
    else:
        error_msg = f"{a} * {b} != {c}"
        error_hanlder(error_msg, raise_on_error)

But on second thought, when raise_on_error is False, error_handler will return False to verify_multiply, not from verify_multiply to its caller (which is my intent), right?

Is there any way to wrap the error handling code into a separate function to be re-used, and let False be returned to verify_multiply's caller when raise_on_error is not True?

I am asking this question because the error handling snippet was needed by a handful verifiers, and it feels awkward to repeat the same code over and over. But the return point is my concern.

1 Answers

Could you return the result of the error_handler invocation?

def verify_multiply(a: int, b: int, c: int, raise_on_error=True):
    if a * b == c:
        return True
    else:
        error_msg = f"{a} * {b} != {c}"
        return error_handler(error_msg, raise_on_error)

The error_handler function only returns when raise_on_error == False, in the other case, an error is raised, which would get raised from verify_multiply even with the added return.

Or here's another way to refactor:

def error_handler(error_msg, raise_on_error=True):
    if raise_on_error:
        raise ValueError(error_msg)
    else:
        log.error(error_msg)


def verify_multiply(a: int, b: int, c: int, raise_on_error=True):
    if a * b == c:
        return True
    else:
        error_msg = f"{a} * {b} != {c}"
        error_handler(error_msg, raise_on_error)
        return False

I think this is a bit more consistent and easy to read since you can see the return value of verify_multiply at a glance and raise_on_error isn't expected to both return something and raise.

Related