Skip to main content

Python Error Handling

Fundamentals Deep Dive

Python Error Handling

Failures happen. Learn how to anticipate them, react with friendly messages, and keep your program from crashing unexpectedly.

try/except anatomy

try:
payload = json.loads(body)
except json.JSONDecodeError as exc:
logger.error("Invalid JSON: %s", exc)
  • Catch the most specific exception you can.
  • Chain exceptions with raise ... from exc to preserve context.

finally + else

try:
resource = acquire()
except ConnectionError:
fallback()
else:
process(resource)
finally:
release(resource)
  • else executes when no exception occurs.
  • finally always executes, perfect for cleanup.

Custom exceptions

class PaymentError(Exception):
"""Base exception for payment failures."""

class CardDeclined(PaymentError):
...

Benefits:

  • Communicate domain-specific issues.
  • Catch broad base classes when needed.

Raising exceptions

if not user.active:
raise PermissionError("User inactive")

Always raise exceptions with helpful messages. Avoid silent failures unless they're intentional.

Logging and observability

  • Use logging.exception inside except blocks to capture stack traces.
  • Surface fatal errors to monitoring systems (Sentry, Rollbar).

Next up in your learning path

Frequently Asked Questions

Should I use bare `except`?

No. Bare `except` catches `SystemExit` and `KeyboardInterrupt`, making it harder to stop your program. Always specify the exception class.

What about `try/except/pass`?

Swallowing exceptions hides real issues. If you truly want to ignore an error, at least add a comment explaining why.

How do I handle asynchronous errors?

Wrap awaitable calls in try/except inside async functions or use event-loop specific hooks (e.g., `loop.set_exception_handler`).