Errors are raised as exceptions and caught with `try`/`except`. `else` runs if no exception occurred; `finally` always runs.
python
def safe_divide(a, b):
try:
return a / b
except ZeroDivisionError:
return None
finally:
print("attempted division")Catch specific exception types rather than a bare `except:`, and raise your own with `raise ValueError("message")`. Custom exceptions subclass `Exception`:
python
class InsufficientFunds(Exception):
pass