8. Error Handling
Catch only what you expect, clean up reliably, and preserve useful error context.
Question: How does Python handle errors?
Answer: Python uses try...except
blocks. You try
a block of code, and if an error (exception) occurs, the except
block for that specific error type is executed. The finally
block runs no matter what, which is useful for cleanup operations.
try:
result = 10 / 0
except ZeroDivisionError:
print("Cannot divide by zero!")
finally:
print("This always runs.")
Question: What is a context manager?
Answer: A context manager is an object designed to be used with the with
statement. It guarantees that setup and teardown operations (like opening and closing a file or a database connection) are always performed correctly.
Question: What is
try/except/else/finally
flow?
Answer: else
runs only if no exception occurred in the try
block; finally
runs always. Use else
for code that should not run if an exception happened.
try:
x = parse(data)
except ValueError:
x = default
else:
cache.save(x)
finally:
cleanup()
Question: How do you define custom exceptions and chain exceptions?
Answer: Subclass Exception
for domain errors; use raise NewError(...) from err
to preserve the original cause.
class ConfigError(Exception):
pass
try:
load()
except FileNotFoundError as e:
raise ConfigError("config missing") from e
Question: How to create your own context manager?
Answer: Implement __enter__
/__exit__
or use contextlib.contextmanager
for a generator-based approach.
from contextlib import contextmanager
@contextmanager
def opened(path, mode):
f = open(path, mode, encoding="utf-8")
try:
yield f
finally:
f.close()
Question: How do you re-raise or suppress exceptions?
Answer: Use raise
inside except
to re-raise; use contextlib.suppress
to intentionally ignore specific exceptions.
try:
risky()
except ValueError:
# log... then re-raise
raise
from contextlib import suppress
with suppress(FileNotFoundError):
Path("maybe.txt").unlink()