22
33use crate :: {
44 data_converters:: {
5- DecodablePayloads , DefaultFailureConverter , FailureConverter , GenericPayloadConverter ,
6- PayloadConversionError , PayloadConverter , RawValue , SerializationContext ,
7- SerializationContextData , TemporalDeserializable , TemporalSerializable ,
5+ DecodablePayloads , GenericPayloadConverter , PayloadConversionError , PayloadConverter ,
6+ RawValue , SerializationContext , SerializationContextData , TemporalDeserializable ,
7+ TemporalSerializable ,
88 } ,
99 protos:: {
1010 coresdk:: child_workflow:: StartChildWorkflowExecutionFailedCause ,
@@ -210,6 +210,11 @@ impl ApplicationFailure {
210210 self . failure . as_ref ( )
211211 }
212212
213+ /// Consumes this application failure and returns the retained proto failure, if one exists.
214+ pub fn into_failure ( self ) -> Option < Failure > {
215+ self . failure
216+ }
217+
213218 /// Returns the normalized cause, if any.
214219 pub fn cause ( & self ) -> Option < & IncomingError > {
215220 self . cause . as_deref ( )
@@ -284,16 +289,6 @@ impl From<PayloadConversionError> for ApplicationFailure {
284289 }
285290}
286291
287- impl From < ApplicationFailure > for Failure {
288- fn from ( value : ApplicationFailure ) -> Self {
289- DefaultFailureConverter . to_failure (
290- OutgoingError :: Workflow ( OutgoingWorkflowError :: Application ( Box :: new ( value) ) ) ,
291- & PayloadConverter :: default ( ) ,
292- & SerializationContextData :: None ,
293- )
294- }
295- }
296-
297292/// A typed outbound error surface used before encoding to a Temporal failure proto.
298293#[ derive( Debug , thiserror:: Error ) ]
299294pub enum OutgoingError {
@@ -444,7 +439,9 @@ impl IncomingError {
444439 /// Consumes this normalized error and returns the retained proto failure.
445440 pub fn into_failure ( self ) -> Failure {
446441 match self {
447- IncomingError :: Application ( err) => err. into ( ) ,
442+ IncomingError :: Application ( err) => err
443+ . into_failure ( )
444+ . expect ( "decoded application failures retain their original proto" ) ,
448445 IncomingError :: Timeout ( err) => err. into_failure ( ) ,
449446 IncomingError :: Cancelled ( err) => err. into_failure ( ) ,
450447 IncomingError :: Terminated ( err) => err. into_failure ( ) ,
@@ -1038,38 +1035,53 @@ impl ChildWorkflowSignalError {
10381035pub struct ChildWorkflowSignalFailureError {
10391036 failure : Failure ,
10401037 error : Box < IncomingError > ,
1041- cause : Option < Box < IncomingError > > ,
10421038}
10431039
10441040impl ChildWorkflowSignalFailureError {
10451041 /// Creates a child-workflow signal failure wrapper.
1046- pub ( crate ) fn new (
1047- failure : Failure ,
1048- error : IncomingError ,
1049- cause : Option < IncomingError > ,
1050- ) -> Self {
1042+ pub ( crate ) fn new ( failure : Failure , error : IncomingError ) -> Self {
10511043 Self {
10521044 failure,
10531045 error : Box :: new ( error) ,
1054- cause : cause. map ( Box :: new) ,
10551046 }
10561047 }
10571048
1049+ /// Returns the retained top-level proto failure.
1050+ pub fn failure ( & self ) -> & Failure {
1051+ & self . failure
1052+ }
1053+
1054+ /// Returns the normalized direct cause of the child-workflow signal failure, if any.
1055+ pub fn cause ( & self ) -> Option < & IncomingError > {
1056+ self . error . cause ( )
1057+ }
1058+
10581059 /// Returns the direct decoded incoming error represented by the top-level proto failure.
10591060 pub fn error ( & self ) -> & IncomingError {
10601061 & self . error
10611062 }
10621063}
10631064
1064- impl_incoming_failure_wrapper ! ( ChildWorkflowSignalFailureError ) ;
1065+ impl std:: fmt:: Display for ChildWorkflowSignalFailureError {
1066+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
1067+ self . failure . fmt ( f)
1068+ }
1069+ }
1070+
1071+ impl std:: error:: Error for ChildWorkflowSignalFailureError {
1072+ fn source ( & self ) -> Option < & ( dyn std:: error:: Error + ' static ) > {
1073+ self . cause ( )
1074+ . map ( |cause| cause as & ( dyn std:: error:: Error + ' static ) )
1075+ }
1076+ }
10651077
10661078#[ cfg( test) ]
10671079mod tests {
10681080 use super :: * ;
10691081 use crate :: {
10701082 data_converters:: {
1071- GenericPayloadConverter , PayloadConverter , SerializationContext ,
1072- SerializationContextData ,
1083+ DefaultFailureConverter , FailureConverter , GenericPayloadConverter , PayloadConverter ,
1084+ SerializationContext , SerializationContextData ,
10731085 } ,
10741086 protos:: temporal:: api:: { common:: v1:: Payload , failure:: v1:: failure:: FailureInfo } ,
10751087 } ;
@@ -1098,14 +1110,19 @@ mod tests {
10981110 ..Default :: default ( )
10991111 } ] ,
11001112 } ;
1101- let failure: Failure = ApplicationFailure :: builder ( anyhow:: anyhow!( "oops" ) )
1102- . type_name ( "MyType" . to_owned ( ) )
1103- . non_retryable ( true )
1104- . next_retry_delay ( Duration :: from_secs ( 3 ) )
1105- . category ( ApplicationErrorCategory :: Benign )
1106- . details ( RawValue :: new ( payloads. payloads . clone ( ) ) )
1107- . build ( )
1108- . into ( ) ;
1113+ let failure = DefaultFailureConverter . to_failure (
1114+ OutgoingError :: Workflow ( OutgoingWorkflowError :: Application ( Box :: new (
1115+ ApplicationFailure :: builder ( anyhow:: anyhow!( "oops" ) )
1116+ . type_name ( "MyType" . to_owned ( ) )
1117+ . non_retryable ( true )
1118+ . next_retry_delay ( Duration :: from_secs ( 3 ) )
1119+ . category ( ApplicationErrorCategory :: Benign )
1120+ . details ( RawValue :: new ( payloads. payloads . clone ( ) ) )
1121+ . build ( ) ,
1122+ ) ) ) ,
1123+ & PayloadConverter :: default ( ) ,
1124+ & SerializationContextData :: None ,
1125+ ) ;
11091126 let Some ( FailureInfo :: ApplicationFailureInfo ( info) ) = failure. failure_info else {
11101127 panic ! ( "expected application failure info" ) ;
11111128 } ;
@@ -1123,10 +1140,15 @@ mod tests {
11231140 data : b"details" . to_vec ( ) ,
11241141 ..Default :: default ( )
11251142 } ;
1126- let failure: Failure = ApplicationFailure :: builder ( anyhow:: anyhow!( "oops" ) )
1127- . details ( RawValue :: new ( vec ! [ payload. clone( ) ] ) )
1128- . build ( )
1129- . into ( ) ;
1143+ let failure = DefaultFailureConverter . to_failure (
1144+ OutgoingError :: Workflow ( OutgoingWorkflowError :: Application ( Box :: new (
1145+ ApplicationFailure :: builder ( anyhow:: anyhow!( "oops" ) )
1146+ . details ( RawValue :: new ( vec ! [ payload. clone( ) ] ) )
1147+ . build ( ) ,
1148+ ) ) ) ,
1149+ & PayloadConverter :: default ( ) ,
1150+ & SerializationContextData :: None ,
1151+ ) ;
11301152
11311153 let Some ( FailureInfo :: ApplicationFailureInfo ( info) ) = failure. failure_info else {
11321154 panic ! ( "expected application failure info" ) ;
@@ -1136,10 +1158,15 @@ mod tests {
11361158
11371159 #[ test]
11381160 fn builder_accepts_serializable_details ( ) {
1139- let failure: Failure = ApplicationFailure :: builder ( anyhow:: anyhow!( "oops" ) )
1140- . details ( "details" . to_string ( ) )
1141- . build ( )
1142- . into ( ) ;
1161+ let failure = DefaultFailureConverter . to_failure (
1162+ OutgoingError :: Workflow ( OutgoingWorkflowError :: Application ( Box :: new (
1163+ ApplicationFailure :: builder ( anyhow:: anyhow!( "oops" ) )
1164+ . details ( "details" . to_string ( ) )
1165+ . build ( ) ,
1166+ ) ) ) ,
1167+ & PayloadConverter :: default ( ) ,
1168+ & SerializationContextData :: None ,
1169+ ) ;
11431170
11441171 let Some ( FailureInfo :: ApplicationFailureInfo ( info) ) = failure. failure_info else {
11451172 panic ! ( "expected application failure info" ) ;
@@ -1159,11 +1186,16 @@ mod tests {
11591186 }
11601187
11611188 #[ test]
1162- fn application_failure_into_failure_surfaces_detail_encoding_errors ( ) {
1163- let failure: Failure = ApplicationFailure :: builder ( anyhow:: anyhow!( "oops" ) )
1164- . details ( AlwaysFailsSerialize )
1165- . build ( )
1166- . into ( ) ;
1189+ fn application_failure_encoding_surfaces_detail_encoding_errors ( ) {
1190+ let failure = DefaultFailureConverter . to_failure (
1191+ OutgoingError :: Workflow ( OutgoingWorkflowError :: Application ( Box :: new (
1192+ ApplicationFailure :: builder ( anyhow:: anyhow!( "oops" ) )
1193+ . details ( AlwaysFailsSerialize )
1194+ . build ( ) ,
1195+ ) ) ) ,
1196+ & PayloadConverter :: default ( ) ,
1197+ & SerializationContextData :: None ,
1198+ ) ;
11671199
11681200 assert_eq ! (
11691201 failure. message,
0 commit comments