Exception chaining preserves a selected failure’s causal exception, while a return from finally can override a pending exception or return.
Python exception interview: chained causes and a finally return that hides failure
Operation contract
The accepted import translates an OSError into a ValueError with an explicit cause. The review inspects that cause instead of assuming only the visible exception existed. A deliberately incorrect finally-return function then reports success after raising. Comparing those traces tests whether a developer can identify a suppressed failure, not merely name exception keywords.
Failure and ownership boundary
The incorrect function is included as a failure case and must not become an application cleanup pattern. Use finally for release work and allow the pending failure to continue. Catching BaseException broadly can also swallow process-control exceptions. Python ExitStack: unwind partially acquired resources and Python ExceptionGroup: handle selected failures and retain the rest cover cleanup and multi-error paths without claiming that one translated error explains every failure.
Working program
def accepted_import():
try:
raise OSError("owned fixture input unavailable")
except OSError as cause:
raise ValueError("receipt import rejected") from cause
def incorrect_finally_return():
try:
raise ValueError("receipt rejected")
finally:
return "incorrect success"
try:
accepted_import()
except ValueError as failure:
print("visible:", type(failure).__name__)
print("cause:", type(failure.__cause__).__name__)
print("suppressed failure:", incorrect_finally_return())Output
visible: ValueError
cause: OSError
suppressed failure: incorrect successCosts and limits
The fixture allocates a few exception/traceback objects and retains their causal references during handling. Real tracebacks can keep substantial local state alive, so storing exception objects indefinitely has an ownership cost.
Common Mistakes
- Never return from cleanup merely to produce a reassuring result.
- Inspect the chained cause when diagnosing a translated failure.
Connected lessons
Python exceptions: translate an input error without hiding its cause, Python ExitStack: unwind partially acquired resources, Python ExceptionGroup: handle selected failures and retain the rest.
