diff --git a/temporalio/converter.py b/temporalio/converter.py index d3cb94ce..887f685a 100644 --- a/temporalio/converter.py +++ b/temporalio/converter.py @@ -34,6 +34,7 @@ overload, ) +import google.protobuf.duration_pb2 import google.protobuf.json_format import google.protobuf.message import google.protobuf.symbol_database @@ -843,6 +844,10 @@ def _error_to_failure( failure.application_failure_info.details.CopyFrom( payload_converter.to_payloads_wrapper(error.details) ) + if error.next_retry_delay: + delay = google.protobuf.duration_pb2.Duration() + delay.FromTimedelta(error.next_retry_delay) + failure.application_failure_info.next_retry_delay.CopyFrom(delay) elif isinstance(error, temporalio.exceptions.TimeoutError): failure.timeout_failure_info.SetInParent() failure.timeout_failure_info.timeout_type = ( diff --git a/temporalio/exceptions.py b/temporalio/exceptions.py index d80190ba..be51eddf 100644 --- a/temporalio/exceptions.py +++ b/temporalio/exceptions.py @@ -1,6 +1,7 @@ """Common Temporal exceptions.""" import asyncio +from datetime import timedelta from enum import IntEnum from typing import Any, Optional, Sequence, Tuple @@ -78,6 +79,7 @@ def __init__( *details: Any, type: Optional[str] = None, non_retryable: bool = False, + next_retry_delay: Optional[timedelta] = None, ) -> None: """Initialize an application error.""" super().__init__( @@ -88,6 +90,7 @@ def __init__( self._details = details self._type = type self._non_retryable = non_retryable + self._next_retry_delay = next_retry_delay @property def details(self) -> Sequence[Any]: @@ -109,6 +112,16 @@ def non_retryable(self) -> bool: """ return self._non_retryable + @property + def next_retry_delay(self) -> Optional[timedelta]: + """Delay before the next activity retry attempt. + + User activity code may set this when raising ApplicationError to specify + a delay before the next activity retry. Ignored if set when raising + ApplicationError from workflow code. + """ + return self._next_retry_delay + class CancelledError(FailureError): """Error raised on workflow/activity cancellation."""