Skip to content

Commit bcfae56

Browse files
fix: preserve exception cause
1 parent f8bf6f9 commit bcfae56

File tree

2 files changed

+26
-2
lines changed

2 files changed

+26
-2
lines changed

google/api_core/retry/retry_base.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,10 @@ def build_retry_error(
164164
src_exc,
165165
)
166166
elif exc_list:
167-
# return most recent exception encountered
168-
return exc_list[-1], None
167+
# return most recent exception encountered and its cause
168+
final_exc = exc_list[-1]
169+
cause = getattr(final_exc, '__cause__', None)
170+
return final_exc, cause
169171
else:
170172
# no exceptions were given in exc_list. Raise generic RetryError
171173
return exceptions.RetryError("Unknown error", None), None

tests/unit/retry/test_retry_base.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,28 @@ def test_build_retry_error_empty_list():
7474
assert src.message == "Unknown error"
7575

7676

77+
def test_build_retry_error_preserves_cause():
78+
"""
79+
build_retry_error should preserve __cause__ from chained exceptions.
80+
81+
Regression test for https://github.com/googleapis/python-api-core/issues/880
82+
"""
83+
from google.api_core.retry import build_retry_error
84+
from google.api_core.retry import RetryFailureReason
85+
86+
# Create an exception with explicit cause
87+
cause = ValueError("root cause")
88+
exc = RuntimeError("wrapper")
89+
exc.__cause__ = cause
90+
91+
src, found_cause = build_retry_error(
92+
[exc], RetryFailureReason.NON_RETRYABLE_ERROR, None
93+
)
94+
95+
assert src is exc
96+
assert found_cause is cause
97+
98+
7799
def test_build_retry_error_timeout_message():
78100
"""
79101
should provide helpful error message when timeout is reached

0 commit comments

Comments
 (0)