How does exception handling work in Python, and what is wrong with a bare except?
The full structure has four clauses:
try:
result = risky()
except ValueError as e:
log.warning("bad input: %s", e)
raise
except (IOError, OSError):
...
else:
# runs only if no exception was raised
commit(result)
finally:
# always runs, exception or not
cleanup()Why except: with no exception class is a bug:
- It catches
KeyboardInterruptandSystemExit, so Ctrl-C stops working and the process becomes hard to shut down. - It catches genuine programming errors — a typo producing a
NameError, aTypeErrorfrom a bad refactor — and hides them. The code appears to work while doing nothing. - It gives no information about what you expected to fail.
If you truly need to catch everything, use except Exception:, which excludes the system-exiting ones, log the traceback, and re-raise unless you have a specific reason not to.
Note: Catch the narrowest exception that can actually occur, and keep the try block as short as possible so it cannot accidentally swallow a failure from an unrelated line. raise ... from e preserves the original cause when wrapping.





