re raise the exception from the error handling in the called function, and in the calling function, just check for exceptions:
def some_func():
try:
something_that_could_raise_an_exception()
except SomeException as e:
handle_error()
raise
def calling_function():
try:
some_func()
except SomeException as e:
more_handling()
I'm not a huge fan of having try/excepts everywhere, but I do this when I want to handle the exception in one specific place, but still let the exception bubble up to the top most level, where it will be sent to the gateway logs. In this case, I catch the exception where I want to handle it ONLY, and then re raise it.
I prefer this over returning error codes and whatnot, because you can finely tune your error handling based on the exception type, and it doesn't pollute your return values.
Error handling is a tricky subject and I'm still trying to figure out how to do it in the best possible way, so take all this with a grain of salt and wait for other opinions/read up on the subject... But I'm pretty sure that moving away from C style error returns is a big step forward.