@@ -163,13 +163,51 @@ function compareCompletion(
163163 req : coresdk . workflow_completion . IWorkflowActivationCompletion ,
164164 expected : coresdk . workflow_completion . IWorkflowActivationCompletion
165165) {
166+ const stackTraces = extractFailureStackTraces ( req , expected ) ;
166167 t . deepEqual (
167168 coresdk . workflow_completion . WorkflowActivationCompletion . create ( req ) . toJSON ( ) ,
168169 coresdk . workflow_completion . WorkflowActivationCompletion . create ( {
169170 ...expected ,
170171 runId : t . context . runId ,
171172 } ) . toJSON ( )
172173 ) ;
174+
175+ if ( stackTraces ) {
176+ for ( const { actual, expected } of stackTraces ) {
177+ compareStackTrace ( t , actual , expected ) ;
178+ }
179+ }
180+ }
181+
182+ // Extracts failure stack traces from completions if structure matches, leaving them unchanged if structure differs.
183+ // We leave them unchanged on structure differences as ava's `deepEqual` provides a better failure message.
184+ function extractFailureStackTraces (
185+ req : coresdk . workflow_completion . IWorkflowActivationCompletion ,
186+ expected : coresdk . workflow_completion . IWorkflowActivationCompletion
187+ ) : { actual : string ; expected : string } [ ] | undefined {
188+ const reqCommands = req . successful ?. commands ;
189+ const expectedCommands = expected . successful ?. commands ;
190+ if ( ! reqCommands || ! expectedCommands || reqCommands . length !== expectedCommands . length ) {
191+ return ;
192+ }
193+ for ( let commandIndex = 0 ; commandIndex < reqCommands . length ; commandIndex ++ ) {
194+ const reqStack = reqCommands [ commandIndex ] . failWorkflowExecution ?. failure ?. stackTrace ;
195+ const expectedStack = expectedCommands [ commandIndex ] . failWorkflowExecution ?. failure ?. stackTrace ;
196+ if ( typeof reqStack !== typeof expectedStack ) {
197+ return ;
198+ }
199+ }
200+ const stackTraces : { actual : string ; expected : string } [ ] = [ ] ;
201+ for ( let commandIndex = 0 ; commandIndex < reqCommands . length ; commandIndex ++ ) {
202+ const reqStack = reqCommands [ commandIndex ] . failWorkflowExecution ?. failure ?. stackTrace ;
203+ const expectedStack = expectedCommands [ commandIndex ] . failWorkflowExecution ?. failure ?. stackTrace ;
204+ if ( reqStack && expectedStack ) {
205+ stackTraces . push ( { actual : reqStack , expected : expectedStack } ) ;
206+ delete reqCommands [ commandIndex ] . failWorkflowExecution ?. failure ?. stackTrace ;
207+ delete expectedCommands [ commandIndex ] . failWorkflowExecution ?. failure ?. stackTrace ;
208+ }
209+ }
210+ return stackTraces ;
173211}
174212
175213function makeSuccess (
@@ -307,12 +345,13 @@ function makeCompleteWorkflowExecution(result?: Payload): coresdk.workflow_comma
307345
308346function makeFailWorkflowExecution (
309347 message : string ,
348+ stackTrace ?: string ,
310349 type = 'Error' ,
311350 nonRetryable = true
312351) : coresdk . workflow_commands . IWorkflowCommand {
313352 return {
314353 failWorkflowExecution : {
315- failure : { message, applicationFailureInfo : { type, nonRetryable } , source : 'TypeScriptSDK' } ,
354+ failure : { message, stackTrace , applicationFailureInfo : { type, nonRetryable } , source : 'TypeScriptSDK' } ,
316355 } ,
317356 } ;
318357}
@@ -452,28 +491,22 @@ function cleanWorkflowQueryFailureStackTrace(
452491 return req ;
453492}
454493
455- function removeWorkflowFailureStackTrace (
456- req : coresdk . workflow_completion . IWorkflowActivationCompletion ,
457- commandIndex = 0
458- ) {
459- const stackTrace = req . successful ! . commands ! [ commandIndex ] . failWorkflowExecution ! . failure ! . stackTrace ! ;
460- delete req . successful ! . commands ! [ commandIndex ] . failWorkflowExecution ! . failure ! . stackTrace ;
461- return stackTrace ;
462- }
463-
464494test ( 'throwAsync' , async ( t ) => {
465495 const { workflowType } = t . context ;
466496 const req = cleanWorkflowFailureStackTrace ( await activate ( t , makeStartWorkflow ( workflowType ) ) ) ;
467- const actualStackTrace = removeWorkflowFailureStackTrace ( req ) ;
468- compareCompletion ( t , req , makeSuccess ( [ makeFailWorkflowExecution ( 'failure' ) ] ) ) ;
469- compareStackTrace (
497+ compareCompletion (
470498 t ,
471- actualStackTrace ,
472- dedent `
499+ req ,
500+ makeSuccess ( [
501+ makeFailWorkflowExecution (
502+ 'failure' ,
503+ dedent `
473504 ApplicationFailure: failure
474505 at $CLASS.nonRetryable (common/src/failure.ts)
475506 at throwAsync (test/src/workflows/throw-async.ts)
476507 `
508+ ) ,
509+ ] )
477510 ) ;
478511} ) ;
479512
@@ -773,25 +806,26 @@ test('interruptableWorkflow', async (t) => {
773806 const req = cleanWorkflowFailureStackTrace (
774807 await activate ( t , await makeSignalWorkflow ( 'interrupt' , [ 'just because' ] ) )
775808 ) ;
776- const stackTrace = removeWorkflowFailureStackTrace ( req ) ;
777809 compareCompletion (
778810 t ,
779811 req ,
780812 makeSuccess (
781- [ makeFailWorkflowExecution ( 'just because' , 'Error' , false ) ] ,
782- [ SdkFlags . ProcessWorkflowActivationJobsAsSingleBatch ]
783- )
784- ) ;
785- compareStackTrace (
786- t ,
787- stackTrace ,
788- // The stack trace is weird here and might confuse users, it might be a JS limitation
789- // since the Error stack trace is generated in the constructor.
790- dedent `
813+ [
814+ makeFailWorkflowExecution (
815+ 'just because' ,
816+ // The stack trace is weird here and might confuse users, it might be a JS limitation
817+ // since the Error stack trace is generated in the constructor.
818+ dedent `
791819 ApplicationFailure: just because
792820 at $CLASS.retryable (common/src/failure.ts)
793821 at test/src/workflows/interrupt-signal.ts
794- `
822+ ` ,
823+ 'Error' ,
824+ false
825+ ) ,
826+ ] ,
827+ [ SdkFlags . ProcessWorkflowActivationJobsAsSingleBatch ]
828+ )
795829 ) ;
796830 }
797831} ) ;
@@ -804,23 +838,23 @@ test('failSignalWorkflow', async (t) => {
804838 }
805839 {
806840 const req = cleanWorkflowFailureStackTrace ( await activate ( t , await makeSignalWorkflow ( 'fail' , [ ] ) ) ) ;
807- const stackTrace = removeWorkflowFailureStackTrace ( req ) ;
808841 compareCompletion (
809842 t ,
810843 req ,
811844 makeSuccess (
812- [ makeFailWorkflowExecution ( 'Signal failed' , 'Error' ) ] ,
813- [ SdkFlags . ProcessWorkflowActivationJobsAsSingleBatch ]
814- )
815- ) ;
816- compareStackTrace (
817- t ,
818- stackTrace ,
819- dedent `
845+ [
846+ makeFailWorkflowExecution (
847+ 'Signal failed' ,
848+ dedent `
820849 ApplicationFailure: Signal failed
821850 at $CLASS.nonRetryable (common/src/failure.ts)
822851 at test/src/workflows/fail-signal.ts
823- `
852+ ` ,
853+ 'Error'
854+ ) ,
855+ ] ,
856+ [ SdkFlags . ProcessWorkflowActivationJobsAsSingleBatch ]
857+ )
824858 ) ;
825859 }
826860} ) ;
@@ -844,22 +878,22 @@ test('asyncFailSignalWorkflow', async (t) => {
844878 }
845879 {
846880 const req = cleanWorkflowFailureStackTrace ( await activate ( t , makeFireTimer ( 2 ) ) ) ;
847- const stackTrace = removeWorkflowFailureStackTrace ( req ) ;
848881 compareCompletion (
849882 t ,
850883 req ,
851884 makeSuccess (
852- [ makeFailWorkflowExecution ( 'Signal failed' , 'Error' ) ] ,
853- [ SdkFlags . ProcessWorkflowActivationJobsAsSingleBatch ]
854- )
855- ) ;
856- compareStackTrace (
857- t ,
858- stackTrace ,
859- dedent `
885+ [
886+ makeFailWorkflowExecution (
887+ 'Signal failed' ,
888+ dedent `
860889 ApplicationFailure: Signal failed
861890 at $CLASS.nonRetryable (common/src/failure.ts)
862- at test/src/workflows/async-fail-signal.ts`
891+ at test/src/workflows/async-fail-signal.ts` ,
892+ 'Error'
893+ ) ,
894+ ] ,
895+ [ SdkFlags . ProcessWorkflowActivationJobsAsSingleBatch ]
896+ )
863897 ) ;
864898 }
865899} ) ;
@@ -1449,7 +1483,6 @@ test('nonCancellableInNonCancellable', async (t) => {
14491483test ( 'cancellationErrorIsPropagated' , async ( t ) => {
14501484 const { workflowType, logs } = t . context ;
14511485 const req = cleanWorkflowFailureStackTrace ( await activate ( t , makeStartWorkflow ( workflowType ) ) , 2 ) ;
1452- const stackTrace = removeWorkflowFailureStackTrace ( req , 2 ) ;
14531486 compareCompletion (
14541487 t ,
14551488 req ,
@@ -1460,25 +1493,21 @@ test('cancellationErrorIsPropagated', async (t) => {
14601493 failWorkflowExecution : {
14611494 failure : {
14621495 message : 'Cancellation scope cancelled' ,
1463- canceledFailureInfo : { } ,
1464- source : 'TypeScriptSDK' ,
1465- } ,
1466- } ,
1467- } ,
1468- ] )
1469- ) ;
1470- compareStackTrace (
1471- t ,
1472- stackTrace ,
1473- dedent `
1496+ stackTrace : dedent `
14741497 CancelledFailure: Cancellation scope cancelled
14751498 at CancellationScope.cancel (workflow/src/cancellation-scope.ts)
14761499 at test/src/workflows/cancellation-error-is-propagated.ts
14771500 at CancellationScope.runInContext (workflow/src/cancellation-scope.ts)
14781501 at CancellationScope.run (workflow/src/cancellation-scope.ts)
14791502 at $CLASS.cancellable (workflow/src/cancellation-scope.ts)
14801503 at cancellationErrorIsPropagated (test/src/workflows/cancellation-error-is-propagated.ts)
1481- `
1504+ ` ,
1505+ canceledFailureInfo : { } ,
1506+ source : 'TypeScriptSDK' ,
1507+ } ,
1508+ } ,
1509+ } ,
1510+ ] )
14821511 ) ;
14831512 t . deepEqual ( logs , [ ] ) ;
14841513} ) ;
@@ -1664,9 +1693,13 @@ test('resolve activity with failure - http', async (t) => {
16641693 } ,
16651694 } )
16661695 ) ;
1667- const stackTrace = removeWorkflowFailureStackTrace ( completion ) ;
1668- compareCompletion ( t , completion , makeSuccess ( [ makeFailWorkflowExecution ( 'Connection timeout' , 'MockError' ) ] ) ) ;
1669- compareStackTrace ( t , stackTrace , 'ApplicationFailure: Connection timeout' ) ;
1696+ compareCompletion (
1697+ t ,
1698+ completion ,
1699+ makeSuccess ( [
1700+ makeFailWorkflowExecution ( 'Connection timeout' , 'ApplicationFailure: Connection timeout' , 'MockError' ) ,
1701+ ] )
1702+ ) ;
16701703 }
16711704} ) ;
16721705
@@ -1877,16 +1910,19 @@ test('tryToContinueAfterCompletion', async (t) => {
18771910 const { workflowType } = t . context ;
18781911 {
18791912 const completion = cleanWorkflowFailureStackTrace ( await activate ( t , makeStartWorkflow ( workflowType ) ) ) ;
1880- const stackTrace = removeWorkflowFailureStackTrace ( completion ) ;
1881- compareCompletion ( t , completion , makeSuccess ( [ makeFailWorkflowExecution ( 'fail before continue' ) ] ) ) ;
1882- compareStackTrace (
1913+ compareCompletion (
18831914 t ,
1884- stackTrace ,
1885- dedent `
1915+ completion ,
1916+ makeSuccess ( [
1917+ makeFailWorkflowExecution (
1918+ 'fail before continue' ,
1919+ dedent `
18861920 ApplicationFailure: fail before continue
18871921 at $CLASS.nonRetryable (common/src/failure.ts)
18881922 at tryToContinueAfterCompletion (test/src/workflows/try-to-continue-after-completion.ts)
18891923 `
1924+ ) ,
1925+ ] )
18901926 ) ;
18911927 }
18921928} ) ;
0 commit comments