Skip to content

Commit e8b163e

Browse files
authored
Allow TaskFailedError to be constructed from Exception (#99)
* Allow TaskFailedError to be constructed from Exception * Propogate inner exceptions in FailureDetails * Allow passing exception to fail()
1 parent a95501a commit e8b163e

File tree

2 files changed

+13
-4
lines changed

2 files changed

+13
-4
lines changed

durabletask/internal/helpers.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,11 +116,18 @@ def new_sub_orchestration_failed_event(event_id: int, ex: Exception) -> pb.Histo
116116
)
117117

118118

119-
def new_failure_details(ex: Exception) -> pb.TaskFailureDetails:
119+
def new_failure_details(ex: Exception, _visited: Optional[set[int]] = None) -> pb.TaskFailureDetails:
120+
if _visited is None:
121+
_visited = set()
122+
_visited.add(id(ex))
123+
inner: Optional[BaseException] = ex.__cause__ or ex.__context__
124+
if len(_visited) > 10 or (inner and id(inner) in _visited) or not isinstance(inner, Exception):
125+
inner = None
120126
return pb.TaskFailureDetails(
121127
errorType=type(ex).__name__,
122128
errorMessage=str(ex),
123-
stackTrace=wrappers_pb2.StringValue(value=''.join(traceback.format_tb(ex.__traceback__)))
129+
stackTrace=wrappers_pb2.StringValue(value=''.join(traceback.format_tb(ex.__traceback__))),
130+
innerFailure=new_failure_details(inner, _visited) if inner else None
124131
)
125132

126133

durabletask/task.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -302,8 +302,10 @@ def stack_trace(self) -> Optional[str]:
302302
class TaskFailedError(Exception):
303303
"""Exception type for all orchestration task failures."""
304304

305-
def __init__(self, message: str, details: pb.TaskFailureDetails):
305+
def __init__(self, message: str, details: Union[pb.TaskFailureDetails, Exception]):
306306
super().__init__(message)
307+
if isinstance(details, Exception):
308+
details = pbh.new_failure_details(details)
307309
self._details = FailureDetails(
308310
details.errorMessage,
309311
details.errorType,
@@ -424,7 +426,7 @@ def complete(self, result: T):
424426
if self._parent is not None:
425427
self._parent.on_child_completed(self)
426428

427-
def fail(self, message: str, details: pb.TaskFailureDetails):
429+
def fail(self, message: str, details: Union[Exception, pb.TaskFailureDetails]):
428430
if self._is_complete:
429431
raise ValueError('The task has already completed.')
430432
self._exception = TaskFailedError(message, details)

0 commit comments

Comments
 (0)