@@ -577,6 +577,8 @@ class FailWorkflow:
577577
578578 message : str
579579 exception_type : str | None = None
580+ exception_class : str | None = None
581+ exception : dict [str , Any ] | None = None
580582 non_retryable : bool = False
581583
582584 def to_server_command (
@@ -593,6 +595,10 @@ def to_server_command(
593595 }
594596 if self .exception_type is not None :
595597 cmd ["exception_type" ] = self .exception_type
598+ if self .exception_class is not None :
599+ cmd ["exception_class" ] = self .exception_class
600+ if self .exception is not None :
601+ cmd ["exception" ] = self .exception
596602 if self .non_retryable :
597603 cmd ["non_retryable" ] = True
598604 return cmd
@@ -1870,6 +1876,41 @@ def _fail_update_from_exception(update_id: str, prefix: str, exc: Exception) ->
18701876 )
18711877
18721878
1879+ def _exception_class_name (exc : BaseException ) -> str :
1880+ return f"{ type (exc ).__module__ } .{ type (exc ).__qualname__ } "
1881+
1882+
1883+ def _fail_workflow_from_exception (exc : BaseException , * , prefix : str | None = None ) -> FailWorkflow :
1884+ message = str (exc ) or type (exc ).__name__
1885+ if prefix :
1886+ message = f"{ prefix } : { message } "
1887+
1888+ exception_type = type (exc ).__name__
1889+ exception_class = _exception_class_name (exc )
1890+ exception : dict [str , Any ] | None = None
1891+ cause = exc .__cause__
1892+ activity_failure = exc if isinstance (exc , ActivityFailed ) else cause if isinstance (cause , ActivityFailed ) else None
1893+ if isinstance (activity_failure , ActivityFailed ):
1894+ exception_type = activity_failure .exception_type or type (activity_failure ).__name__
1895+ exception_class = activity_failure .exception_class or _exception_class_name (activity_failure )
1896+ exception = {
1897+ "type" : exception_type ,
1898+ "class" : exception_class ,
1899+ "message" : message ,
1900+ }
1901+ if activity_failure .activity_type is not None :
1902+ exception ["activity_type" ] = activity_failure .activity_type
1903+ if activity_failure .activity_attempt_id is not None :
1904+ exception ["activity_attempt_id" ] = activity_failure .activity_attempt_id
1905+
1906+ return FailWorkflow (
1907+ message = message ,
1908+ exception_type = exception_type ,
1909+ exception_class = exception_class ,
1910+ exception = exception ,
1911+ )
1912+
1913+
18731914def _history_event_type (event : Mapping [str , Any ]) -> str | None :
18741915 value = event .get ("event_type" ) or event .get ("type" )
18751916 return value if isinstance (value , str ) and value else None
@@ -2781,9 +2822,9 @@ def _terminal_state(value: Any, *, include_pending: bool) -> _ReplayState:
27812822 try :
27822823 satisfied = bool (cmd .predicate ())
27832824 except Exception as exc :
2784- return _state ([FailWorkflow (
2785- message = f"wait_condition predicate raised: { exc } " ,
2786- exception_type = type ( exc ). __name__ ,
2825+ return _state ([_fail_workflow_from_exception (
2826+ exc ,
2827+ prefix = "wait_condition predicate raised" ,
27872828 )])
27882829 if resolution == "satisfied" :
27892830 if has_reopened_same_wait :
@@ -2848,14 +2889,8 @@ def _terminal_state(value: Any, *, include_pending: bool) -> _ReplayState:
28482889 except Exception as exc :
28492890 if isinstance (exc , NonDeterministicReplayError ):
28502891 raise
2851- return _state ([FailWorkflow (
2852- message = str (exc ),
2853- exception_type = type (exc ).__name__ ,
2854- )])
2892+ return _state ([_fail_workflow_from_exception (exc )])
28552893 except NonDeterministicReplayError :
28562894 raise
28572895 except Exception as exc :
2858- return _state ([FailWorkflow (
2859- message = str (exc ),
2860- exception_type = type (exc ).__name__ ,
2861- )])
2896+ return _state ([_fail_workflow_from_exception (exc )])
0 commit comments