Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

Exception chaining is a mechanism in Python that links a newly raised exception to an originally caught exception, preserving the traceback history of both. This linkage is managed internally via the __context__, __cause__, and __suppress_context__ dunder attributes on the exception instances. Python supports two types of exception chaining: implicit and explicit, alongside a mechanism to intentionally suppress chaining.

Implicit Exception Chaining

Implicit chaining occurs automatically when a secondary exception is raised while an original exception is actively being handled (i.e., inside an except or finally block). When this happens, Python automatically assigns the original exception instance to the __context__ attribute of the newly raised exception instance. During traceback rendering, Python outputs a message indicating that an exception occurred during the handling of another exception.
try:
    1 / 0
except ZeroDivisionError as original_exc:
    # A new exception is raised during handling.
    # Python automatically sets the new NameError instance's __context__ = original_exc
    print(undefined_variable)

Explicit Exception Chaining

Explicit chaining is triggered manually using the raise ... from ... syntax. This allows a developer to intentionally wrap an underlying exception with a new exception. When explicit chaining is used, Python assigns the original exception instance to the __cause__ attribute of the new exception instance. Additionally, it sets the __suppress_context__ boolean attribute on the new exception instance to True. During traceback rendering, Python outputs a message indicating that the original exception was the direct cause of the new exception.
try:
    int("invalid_string")
except ValueError as original_exc:
    # Explicitly chains the new RuntimeError to the ValueError.
    # Python sets the new RuntimeError instance's __cause__ = original_exc
    # Python sets the new RuntimeError instance's __suppress_context__ = True
    raise RuntimeError("Failed to parse integer") from original_exc

Disabling Exception Chaining

To intentionally break the chain and prevent the original exception’s traceback from being displayed, Python provides the raise ... from None syntax. This syntax explicitly sets the __cause__ attribute of the new exception instance to None and sets its __suppress_context__ attribute to True. Because __suppress_context__ is true, the default traceback printer ignores the __context__ attribute, effectively hiding the original exception from the standard output.
try:
    open("missing_file.txt")
except FileNotFoundError as original_exc:
    # Suppresses the original exception.
    # Python sets the new RuntimeError instance's __cause__ = None
    # Python sets the new RuntimeError instance's __suppress_context__ = True
    raise RuntimeError("Missing required configuration") from None

Internal Attribute Resolution

When Python’s default exception handler prints a traceback, it evaluates the chaining attributes on the exception instance in the following order:
  1. It checks __cause__. If __cause__ is an exception object, it prints the explicit chain.
  2. If __cause__ is None, it checks __suppress_context__.
  3. If __suppress_context__ is False, it checks __context__. If __context__ is an exception object, it prints the implicit chain.
  4. If __suppress_context__ is True, it ignores __context__ entirely.
Master Python with Deep Grasping Methodology!Learn More