Python try except โ exception handling patterns
try except block, except with type, else clause, finally clause, raise statement, exception hierarchy, catching multiple exceptions
Exception Handling
Exceptions stop program execution. Wrap risky code in try and handle specific exceptions in except clauses. Never use a bare except: โ it silently catches everything including KeyboardInterrupt.
def safe_divide(a, b):
try:
result = a / b
except ZeroDivisionError:
print("Cannot divide by zero")
return None
except TypeError as e:
print(f"Type error: {e}")
return None
else:
print("Success") # runs only if no exception
return result
finally:
print("Always runs") # cleanup goes here
print(safe_divide(10, 2)) # Success, Always runs, 5.0
print(safe_divide(10, 0)) # error message, Always runs, None
Raising Exceptions
def set_age(age):
if not isinstance(age, int) or age < 0:
raise ValueError(f"Invalid age: {age}")
return age
try:
set_age(-5)
except ValueError as e:
print(e) # Invalid age: -5
Catch the most specific exception first. Python checks except clauses top-to-bottom and uses the first match.
Exception handling should be surgical โ catch what you expect, let everything else propagate. A broad except clause that silently swallows unexpected errors is one of the hardest bugs to track down because the program appears to continue normally while operating on corrupted state. The else clause on a try block is underused but useful: code in else runs only when no exception was raised, clearly separating the success path from the error handling. Log exceptions with logging.exception() in production code โ it captures the full traceback automatically.
