Skip to content

Commit 4e4f84a

Browse files
author
German Ilin
committed
fix(converter): handle serialization of recursive exceptions
It is kind of an easy mistake to do in python: ``` try: raise ValueError("test") except Exception as e: raise e from e ``` The reraised exception will have e.__cause__ referencing itself resulting in failure to serialize error and python sdk won't report anything resulting in retries and startToClose timeouts.
1 parent a90f6d4 commit 4e4f84a

File tree

2 files changed

+16
-1
lines changed

2 files changed

+16
-1
lines changed

temporalio/converter.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -800,7 +800,8 @@ def to_failure(
800800
str(exception), type=exception.__class__.__name__
801801
)
802802
failure_error.__traceback__ = exception.__traceback__
803-
failure_error.__cause__ = exception.__cause__
803+
if exception.__cause__ and exception.__cause__ != exception:
804+
failure_error.__cause__ = exception.__cause__
804805
self._error_to_failure(failure_error, payload_converter, failure)
805806
# Encode common attributes if requested
806807
if self._encode_common_attributes:

tests/test_converter.py

+14
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,20 @@ async def decode(self, payloads: Sequence[Payload]) -> List[Payload]:
490490
return list(wrapper.payloads)
491491

492492

493+
async def test_broken_exception_serialization():
494+
conv = DataConverter(
495+
payload_codec=SimpleCodec(),
496+
)
497+
try:
498+
try:
499+
raise ValueError("test")
500+
except Exception as e:
501+
raise e from e
502+
except Exception as e:
503+
failure = Failure()
504+
conv.failure_converter.to_failure(e, conv.payload_converter, failure)
505+
506+
493507
async def test_failure_encoded_attributes():
494508
try:
495509
raise ApplicationError("some message", "some detail")

0 commit comments

Comments
 (0)