Skip to content

Commit c535787

Browse files
chore: update tests to support Node 24 stack traces
1 parent 69264b0 commit c535787

File tree

4 files changed

+111
-65
lines changed

4 files changed

+111
-65
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ packages/*/package-lock.json
1616
# One test creates persisted SQLite DBs; they should normally be deleted automatically,
1717
# but may be left behind in some error scenarios.
1818
packages/test/temporal-db-*.sqlite
19+
.DS_Store

package-lock.json

Lines changed: 23 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/test/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
"@types/node-fetch": "^2.6.10",
6666
"@types/pidusage": "^2.0.5",
6767
"@types/uuid": "^9.0.7",
68+
"escape-string-regexp": "^5.0.0",
6869
"fs-extra": "^11.2.0",
6970
"npm-run-all": "^4.1.5",
7071
"pidusage": "^3.0.2"

packages/test/src/test-workflows.ts

Lines changed: 86 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import vm from 'node:vm';
44
import anyTest, { ExecutionContext, TestFn } from 'ava';
55
import dedent from 'dedent';
66
import Long from 'long'; // eslint-disable-line import/no-named-as-default
7+
import escapeStringRexep from 'escape-string-regexp';
78
import {
89
ApplicationFailure,
910
defaultFailureConverter,
@@ -172,6 +173,14 @@ function compareCompletion(
172173
);
173174
}
174175

176+
// Compare stack traces while handling $CLASS keyword to match any identifier that isn't consistent across Node versions.
177+
// As of Node 24.6.0 type names are now present on source mapped stack traces
178+
// See [f33e0fcc83954f728fcfd2ef6ae59435bc4af059](https://github.com/nodejs/node/commit/f33e0fcc83954f728fcfd2ef6ae59435bc4af059)
179+
function compareFailureStackTrace(t: ExecutionContext<Context>, actual: string, expected: string) {
180+
const escapedTrace = escapeStringRexep(expected).replaceAll('\\$CLASS', '(?:[A-Za-z]+)');
181+
t.regex(actual, RegExp(`^${escapedTrace}$`));
182+
}
183+
175184
function makeSuccess(
176185
commands: coresdk.workflow_commands.IWorkflowCommand[] = [makeCompleteWorkflowExecution()],
177186
usedInternalFlags: SdkFlag[] = []
@@ -307,13 +316,12 @@ function makeCompleteWorkflowExecution(result?: Payload): coresdk.workflow_comma
307316

308317
function makeFailWorkflowExecution(
309318
message: string,
310-
stackTrace: string,
311319
type = 'Error',
312320
nonRetryable = true
313321
): coresdk.workflow_commands.IWorkflowCommand {
314322
return {
315323
failWorkflowExecution: {
316-
failure: { message, stackTrace, applicationFailureInfo: { type, nonRetryable }, source: 'TypeScriptSDK' },
324+
failure: { message, applicationFailureInfo: { type, nonRetryable }, source: 'TypeScriptSDK' },
317325
},
318326
};
319327
}
@@ -453,22 +461,28 @@ function cleanWorkflowQueryFailureStackTrace(
453461
return req;
454462
}
455463

464+
function removeWorkflowFailureStackTrace(
465+
req: coresdk.workflow_completion.IWorkflowActivationCompletion,
466+
commandIndex = 0
467+
) {
468+
const stackTrace = req.successful!.commands![commandIndex].failWorkflowExecution!.failure!.stackTrace!;
469+
delete req.successful!.commands![commandIndex].failWorkflowExecution!.failure!.stackTrace;
470+
return stackTrace;
471+
}
472+
456473
test('throwAsync', async (t) => {
457474
const { workflowType } = t.context;
458475
const req = cleanWorkflowFailureStackTrace(await activate(t, makeStartWorkflow(workflowType)));
459-
compareCompletion(
476+
const actualStackTrace = removeWorkflowFailureStackTrace(req);
477+
compareCompletion(t, req, makeSuccess([makeFailWorkflowExecution('failure')]));
478+
compareFailureStackTrace(
460479
t,
461-
req,
462-
makeSuccess([
463-
makeFailWorkflowExecution(
464-
'failure',
465-
dedent`
480+
actualStackTrace,
481+
dedent`
466482
ApplicationFailure: failure
467-
at Function.nonRetryable (common/src/failure.ts)
483+
at $CLASS.nonRetryable (common/src/failure.ts)
468484
at throwAsync (test/src/workflows/throw-async.ts)
469485
`
470-
),
471-
])
472486
);
473487
});
474488

@@ -768,27 +782,26 @@ test('interruptableWorkflow', async (t) => {
768782
const req = cleanWorkflowFailureStackTrace(
769783
await activate(t, await makeSignalWorkflow('interrupt', ['just because']))
770784
);
785+
const stackTrace = removeWorkflowFailureStackTrace(req);
771786
compareCompletion(
772787
t,
773788
req,
774789
makeSuccess(
775-
[
776-
makeFailWorkflowExecution(
777-
'just because',
778-
// The stack trace is weird here and might confuse users, it might be a JS limitation
779-
// since the Error stack trace is generated in the constructor.
780-
dedent`
781-
ApplicationFailure: just because
782-
at Function.retryable (common/src/failure.ts)
783-
at test/src/workflows/interrupt-signal.ts
784-
`,
785-
'Error',
786-
false
787-
),
788-
],
790+
[makeFailWorkflowExecution('just because', 'Error', false)],
789791
[SdkFlags.ProcessWorkflowActivationJobsAsSingleBatch]
790792
)
791793
);
794+
compareFailureStackTrace(
795+
t,
796+
stackTrace,
797+
// The stack trace is weird here and might confuse users, it might be a JS limitation
798+
// since the Error stack trace is generated in the constructor.
799+
dedent`
800+
ApplicationFailure: just because
801+
at $CLASS.retryable (common/src/failure.ts)
802+
at test/src/workflows/interrupt-signal.ts
803+
`
804+
);
792805
}
793806
});
794807

@@ -800,24 +813,24 @@ test('failSignalWorkflow', async (t) => {
800813
}
801814
{
802815
const req = cleanWorkflowFailureStackTrace(await activate(t, await makeSignalWorkflow('fail', [])));
816+
const stackTrace = removeWorkflowFailureStackTrace(req);
803817
compareCompletion(
804818
t,
805819
req,
806820
makeSuccess(
807-
[
808-
makeFailWorkflowExecution(
809-
'Signal failed',
810-
dedent`
811-
ApplicationFailure: Signal failed
812-
at Function.nonRetryable (common/src/failure.ts)
813-
at test/src/workflows/fail-signal.ts
814-
`,
815-
'Error'
816-
),
817-
],
821+
[makeFailWorkflowExecution('Signal failed', 'Error')],
818822
[SdkFlags.ProcessWorkflowActivationJobsAsSingleBatch]
819823
)
820824
);
825+
compareFailureStackTrace(
826+
t,
827+
stackTrace,
828+
dedent`
829+
ApplicationFailure: Signal failed
830+
at $CLASS.nonRetryable (common/src/failure.ts)
831+
at test/src/workflows/fail-signal.ts
832+
`
833+
);
821834
}
822835
});
823836

@@ -840,23 +853,23 @@ test('asyncFailSignalWorkflow', async (t) => {
840853
}
841854
{
842855
const req = cleanWorkflowFailureStackTrace(await activate(t, makeFireTimer(2)));
856+
const stackTrace = removeWorkflowFailureStackTrace(req);
843857
compareCompletion(
844858
t,
845859
req,
846860
makeSuccess(
847-
[
848-
makeFailWorkflowExecution(
849-
'Signal failed',
850-
dedent`
851-
ApplicationFailure: Signal failed
852-
at Function.nonRetryable (common/src/failure.ts)
853-
at test/src/workflows/async-fail-signal.ts`,
854-
'Error'
855-
),
856-
],
861+
[makeFailWorkflowExecution('Signal failed', 'Error')],
857862
[SdkFlags.ProcessWorkflowActivationJobsAsSingleBatch]
858863
)
859864
);
865+
compareFailureStackTrace(
866+
t,
867+
stackTrace,
868+
dedent`
869+
ApplicationFailure: Signal failed
870+
at $CLASS.nonRetryable (common/src/failure.ts)
871+
at test/src/workflows/async-fail-signal.ts`
872+
);
860873
}
861874
});
862875

@@ -1445,6 +1458,7 @@ test('nonCancellableInNonCancellable', async (t) => {
14451458
test('cancellationErrorIsPropagated', async (t) => {
14461459
const { workflowType, logs } = t.context;
14471460
const req = cleanWorkflowFailureStackTrace(await activate(t, makeStartWorkflow(workflowType)), 2);
1461+
const stackTrace = removeWorkflowFailureStackTrace(req, 2);
14481462
compareCompletion(
14491463
t,
14501464
req,
@@ -1455,22 +1469,26 @@ test('cancellationErrorIsPropagated', async (t) => {
14551469
failWorkflowExecution: {
14561470
failure: {
14571471
message: 'Cancellation scope cancelled',
1458-
stackTrace: dedent`
1459-
CancelledFailure: Cancellation scope cancelled
1460-
at CancellationScope.cancel (workflow/src/cancellation-scope.ts)
1461-
at test/src/workflows/cancellation-error-is-propagated.ts
1462-
at CancellationScope.runInContext (workflow/src/cancellation-scope.ts)
1463-
at CancellationScope.run (workflow/src/cancellation-scope.ts)
1464-
at Function.cancellable (workflow/src/cancellation-scope.ts)
1465-
at cancellationErrorIsPropagated (test/src/workflows/cancellation-error-is-propagated.ts)
1466-
`,
14671472
canceledFailureInfo: {},
14681473
source: 'TypeScriptSDK',
14691474
},
14701475
},
14711476
},
14721477
])
14731478
);
1479+
compareFailureStackTrace(
1480+
t,
1481+
stackTrace,
1482+
dedent`
1483+
CancelledFailure: Cancellation scope cancelled
1484+
at CancellationScope.cancel (workflow/src/cancellation-scope.ts)
1485+
at test/src/workflows/cancellation-error-is-propagated.ts
1486+
at CancellationScope.runInContext (workflow/src/cancellation-scope.ts)
1487+
at CancellationScope.run (workflow/src/cancellation-scope.ts)
1488+
at $CLASS.cancellable (workflow/src/cancellation-scope.ts)
1489+
at cancellationErrorIsPropagated (test/src/workflows/cancellation-error-is-propagated.ts)
1490+
`
1491+
);
14741492
t.deepEqual(logs, []);
14751493
});
14761494

@@ -1655,13 +1673,19 @@ test('resolve activity with failure - http', async (t) => {
16551673
},
16561674
})
16571675
);
1676+
const stackTrace = removeWorkflowFailureStackTrace(completion);
16581677
compareCompletion(
16591678
t,
16601679
completion,
16611680
makeSuccess([
1662-
makeFailWorkflowExecution('Connection timeout', 'ApplicationFailure: Connection timeout', 'MockError'),
1681+
makeFailWorkflowExecution('Connection timeout', 'MockError'),
16631682
])
16641683
);
1684+
compareFailureStackTrace(
1685+
t,
1686+
stackTrace,
1687+
'ApplicationFailure: Connection timeout'
1688+
);
16651689
}
16661690
});
16671691

@@ -1872,19 +1896,16 @@ test('tryToContinueAfterCompletion', async (t) => {
18721896
const { workflowType } = t.context;
18731897
{
18741898
const completion = cleanWorkflowFailureStackTrace(await activate(t, makeStartWorkflow(workflowType)));
1875-
compareCompletion(
1899+
const stackTrace = removeWorkflowFailureStackTrace(completion);
1900+
compareCompletion(t, completion, makeSuccess([makeFailWorkflowExecution('fail before continue')]));
1901+
compareFailureStackTrace(
18761902
t,
1877-
completion,
1878-
makeSuccess([
1879-
makeFailWorkflowExecution(
1880-
'fail before continue',
1881-
dedent`
1903+
stackTrace,
1904+
dedent`
18821905
ApplicationFailure: fail before continue
1883-
at Function.nonRetryable (common/src/failure.ts)
1906+
at $CLASS.nonRetryable (common/src/failure.ts)
18841907
at tryToContinueAfterCompletion (test/src/workflows/try-to-continue-after-completion.ts)
18851908
`
1886-
),
1887-
])
18881909
);
18891910
}
18901911
});

0 commit comments

Comments
 (0)