> ## 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.

# Python Exception Chaining

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.

```python theme={"dark"}
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.

```python theme={"dark"}
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.

```python theme={"dark"}
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.

<div
  style={{ 
display: "flex", 
justifyContent: "space-between", 
alignItems: "center", 
maxWidth: "754px", 
padding: "1rem 0",
marginBottom: "24px"
}}
>
  <span style={{ fontWeight: "bold", fontSize: "1.25rem", color: "var(--tw-prose-headings)", fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif" }}>Tired of Poor Python Skills? Fix That With Deep Grasping!</span>

  <a
    href="https://syntblaze.com"
    target="_blank"
    style={{ 
  marginLeft: "24px",
  textDecoration: "none", 
  backgroundColor: "#007AFF",
  color: "#ffffff", 
  padding: "6px 16px", 
  borderRadius: "16px",
  fontSize: "0.9rem",
  fontWeight: "600",
  textAlign: "center",
  transition: "background-color 0.2s ease"
}}
  >
    Learn More
  </a>
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/skill-tracking.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=b9b0305c93bb501c9e767b5c76c88835" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/skill-tracking.png" />

  <img src="https://mintcdn.com/syntblazellc/23tyuOzaWS88qFlc/images/nuggets.png?fit=max&auto=format&n=23tyuOzaWS88qFlc&q=85&s=c86c80197299762989e9b882419b2109" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/nuggets.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/bite-sized-exercises.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=a65f9a38c37ff28ab73ed783c53c60e3" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/bite-sized-exercises.png" />
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap", marginTop: "12px" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/mastery-chain.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=748a1763454713e679260fbb95f154a2" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/mastery-chain.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-previews.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=242f61448ff5dd6deaaab2dccc13b507" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-previews.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-explanations.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=cf0fc1c31f9cd0fc26716781be05fbc9" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-explanations.png" />
</div>
