Interview frequency: …
Short answer
It links the new exception to the original cause through __cause__, so the traceback shows the full chain with the phrase "The above exception was the direct cause...", which preserves diagnostic context.
Explanation
At layer boundaries, translate internal library errors (such as KeyError or database errors) into meaningful domain errors while keeping the original cause through from. Without from, Python links the two exceptions implicitly through __context__ with the message "During handling... another exception occurred", which suggests a bug in the exception handler itself. Use from None only when hiding the cause is deliberate, for example to hide internal details that do not help the user.
Code example
class ConfigError(Exception):
pass
def load_port(env: dict[str, str]) -> int:
try:
return int(env["PORT"])
except KeyError as err:
raise ConfigError("PORT is not set") from err
except ValueError as err:
raise ConfigError("PORT must be a number") from errCommon mistakes
- Raising a new exception without from, so the real cause is lost or presented misleadingly.
- Using from None by default, which makes errors harder to trace in production.
Follow-up questions
- How do you choose the right exception and deal with the exception hierarchy?
- When should you create a custom exception?