Interview frequency: …
Short answer
Raise an exception that precisely expresses the cause of the failure (such as ValueError, KeyError or a domain-specific exception), and catch the narrowest type you can actually handle instead of except Exception everywhere.
Explanation
Regular exceptions inherit from Exception, whereas KeyboardInterrupt and SystemExit inherit directly from BaseException; that is why a bare except: or except BaseException swallows shutdown signals and prevents the program from stopping. Catch the exception in the layer that owns the decision to recover or to translate it into a meaningful error, and let the rest propagate. A broad except Exception is acceptable at the top-level boundary (such as a request handler) for logging and returning a 500.
Code example
def parse_age(raw: str) -> int:
try:
age = int(raw)
except ValueError:
raise ValueError(f"invalid age: {raw!r}") from None
if age < 0:
raise ValueError("age must be positive")
return ageCommon mistakes
- Writing except: pass, so every error disappears, including Ctrl+C.
- Catching Exception in a layer that does not know how to recover and then continuing in an invalid state.