Try it and see:
def failure():
raise ValueError, "Real error"
def apologize():
raise TypeError, "Apology error"
try:
failure()
except ValueError:
apologize()
raise
The result:
Traceback (most recent call last):
File "<pyshell#14>", line 10, in <module>
apologize()
File "<pyshell#14>", line 5, in apologize
raise TypeError, "Apology error"
TypeError: Apology error
The reason: the "real" error from the original function was already caught by the except
. apologize
raises a new error before the raise
is reached. Therefore, the raise
in the except
clause is never executed, and only the apology's error propagates upward. If apologize
raises an error, Python has no way of knowing that you were going to raise a different exception after apologize
.
Note that in Python 3, the traceback will mention both exceptions, with a message explaining how the second one arose:
Traceback (most recent call last):
File "./prog.py", line 9, in <module>
File "./prog.py", line 2, in failure
ValueError: Real error
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "./prog.py", line 11, in <module>
File "./prog.py", line 5, in apologize
TypeError: Apology error
However, the second exception (the "apology" exception) is still the only one that propagates outward and can be caught by a higher-level except
clause. The original exception is mentioned in the traceback but is subsumed in the later one and can no longer be caught.
Exception
, there's not much hierarchy. Questions aside, though, why don't you just try it and see? – Hautboyprint('do_something_dangerous raised {!r}'.format(e))
at least level and see what's going on. – Irruptiveexcept Exception
, not just bareexcept:
. Partly this is to allow him to capture the exception withexcept Exception, e:
(although this is an old blog, so it uses old syntax; you wantexcept Exception as e:
), and partly to avoid catching things likeKeyboardInterrupt
, which you very rarely want to handle. (When you do, make it explicit withexcept BaseException:
. That wasn't an option in older Python, but assuming you're writing for, e.g., 2.6 or 3.0, it is.) – Irruptiveapologize
code in some way, so you can raise an exception that lets you code/the end user know that you failed and then failed to clean up. (Or maybe create the folder in a temporary location on the destination drive/filesystem so the worst-case scenario isn't as bad and maybe doesn't have to be reported.) But otherwise, yeah, that's a perfectly reasonable use to exception-handling code that may raises. – Irruptive