Python · The language, not just syntax

How should exceptions be handled in production Python?

Mediumexceptionserror handlingeafpUpdated Oct 2026
Quiz this track

Short answer

Catch the narrowest exception you can handle, let the rest propagate, and preserve context with raise from. Use finally for cleanup and custom exception hierarchies for domain errors.

Python uses exceptions for both unexpected failures and expected conditions. The try statement supports except for handling, else for code that runs only when no exception occurred, and finally for unconditional cleanup.

python
class PaymentError(Exception):
    pass

def charge(amount):
    if amount <= 0:
        raise ValueError("amount must be positive")
    try:
        return gateway.charge(amount)
    except TimeoutError as exc:
        raise PaymentError("gateway timed out") from exc

try:
    charge(-1)
except ValueError as exc:
    print("invalid input:", exc)
except PaymentError as exc:
    print("payment failed:", exc)
The domain error keeps the original timeout as its cause, so tracebacks show both layers.

Practices that hold up

  • Never use a bare except: it also catches KeyboardInterrupt and SystemExit
  • Use EAFP: try the operation and handle the specific failure rather than pre-checking everything
  • Log once at the boundary where you handle the error, not at every layer
  • Define a small exception hierarchy for the domain and translate third-party errors at the boundary

Swallowing an exception with pass hides bugs and makes incidents hard to diagnose. If you catch and continue, record why and what state was affected. Raising a new exception without from loses the original traceback chain, which is exactly the information you need in production.

Python 3.11 added ExceptionGroup and except* for handling multiple concurrent failures. Use them when a batch operation should report every failure rather than stopping at the first.

Follow-ups you should expect

Interviewers use these to check whether the first answer was understanding or memorisation.

  1. 1Why is a bare except considered harmful?
  2. 2What does raise ... from ... do?
  3. 3When would you use else on a try block?
  4. 4How do you handle multiple failures in a batch operation?

Say it in the interview

I catch only the exceptions I can actually handle, and I let everything else propagate. I use raise from to preserve the original cause, and finally for cleanup. At service boundaries I translate library errors into domain exceptions and log them once with context. I avoid bare except because it swallows interruption signals and hides bugs, and I never silently pass on a failure.

Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.

Related questions

Reading is step one

Now say it out loud.

Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live Python mock interview and get scored feedback on depth, clarity and confidence.