Skip to content

fix: stop hanging on cyclic exception __cause__ chains - #660

Merged
mergify[bot] merged 1 commit into
jd:mainfrom
MohammedAnasNathani:fix/retry-cause-cycle-safe
Jul 29, 2026
Merged

fix: stop hanging on cyclic exception __cause__ chains#660
mergify[bot] merged 1 commit into
jd:mainfrom
MohammedAnasNathani:fix/retry-cause-cycle-safe

Conversation

@MohammedAnasNathani

Copy link
Copy Markdown
Contributor

Summary

Fixes #658.

retry_if_exception_cause_type walked __cause__ until None. A cyclic cause chain never ends, so the predicate spins at 100% CPU and stop conditions never run (they are only checked after the predicate returns).

This is legal Python:

def boom():
    try:
        raise ValueError("inner")
    except ValueError as e:
        raise e from e  # self-referential __cause__

Retrying(
    retry=retry_if_exception_cause_type(KeyError),
    stop=stop_after_attempt(2),
    reraise=True,
)(boom)  # hung forever

Two-node cycles (a.__cause__ = b; b.__cause__ = a) hang the same way.

Fix

Track id(exc) while walking and stop when a cycle is detected — the same idea as the stdlib traceback module’s cycle-safe chain walk.

Tests

  • Self-cause cycle (raise e from e)
  • Two-node mutual cause cycle
  • Existing cause-type tests still pass

Checklist

  • Regression tests
  • Local pytest -k exception_cause green

retry_if_exception_cause_type walked __cause__ until None. Legal cycles
such as ``raise e from e`` (or mutual a<->b causes) never terminate, so
the predicate spins at 100% CPU and stop conditions never run.

Track seen exception ids while walking, matching stdlib traceback's
cycle-safe approach. Regression covers self-cause and two-node cycles.

Fixes jd#658.
Copilot AI review requested due to automatic review settings July 23, 2026 14:37

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@mergify

mergify Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Merge Queue Status

  • Entered queue2026-07-29 10:39 UTC · Rule: default · triggered by rule autoqueue
  • Checks skipped · PR is already up-to-date
  • Merged2026-07-29 10:39 UTC · at b1936f1cc172b17e3fcd45ed84416f7e4c191fc0 · squash

This pull request spent 8 seconds in the queue, including 1 second running CI.

Required conditions to merge

@mergify
mergify Bot merged commit b3c5a9f into jd:main Jul 29, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

retry_if_exception_cause_type spins forever when the exception cause chain contains a cycle (e.g. raise e from e)

3 participants