The other answers are good for the specific case where you can avoid raising the exception in the first place. The more general case where the exception cannot be avoided can be handled a lambda function as follows:
def test(expression, exception_list, on_exception):
try:
return expression()
except exception_list:
return on_exception
if test(lambda: some_function(data), SomeException, None) is None:
report_error('Something happened')
The key point here is that making it a lambda defers evaluation of the expression that might raise an exception until inside the try/except block of the test()
function where it can be caught. test()
returns either the result of the evaluation, or, if an exception in exception_list
is raised, the on_exception
value.
This comes from an idea in the rejected PEP 463. lambda to the Rescue presents the same idea.
(I offered the same answer in response to this question, but I'm repeating it here because this isn't exactly a duplicate question.)