Skip to content

Commit

Permalink
test_runner: include stack of uncaught exceptions
Browse files Browse the repository at this point in the history
PR-URL: #44614
Fixes: #44611
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
  • Loading branch information
MoLow authored and RafaelGSS committed Sep 26, 2022
1 parent 226d90a commit 5ab3bc9
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 7 deletions.
4 changes: 2 additions & 2 deletions lib/internal/test_runner/tap_stream.js
Expand Up @@ -173,7 +173,7 @@ function jsToYaml(indent, name, value) {
}

if (isErrorObj) {
const { kTestCodeFailure, kHookFailure } = lazyLoadTest();
const { kTestCodeFailure, kUnwrapErrors } = lazyLoadTest();
const {
cause,
code,
Expand All @@ -187,7 +187,7 @@ function jsToYaml(indent, name, value) {

// If the ERR_TEST_FAILURE came from an error provided by user code,
// then try to unwrap the original error message and stack.
if (code === 'ERR_TEST_FAILURE' && (failureType === kTestCodeFailure || failureType === kHookFailure)) {
if (code === 'ERR_TEST_FAILURE' && kUnwrapErrors.has(failureType)) {
errStack = cause?.stack ?? errStack;
errCode = cause?.code ?? errCode;
if (failureType === kTestCodeFailure) {
Expand Down
6 changes: 5 additions & 1 deletion lib/internal/test_runner/test.js
Expand Up @@ -13,6 +13,7 @@ const {
PromiseResolve,
ReflectApply,
SafeMap,
SafeSet,
SafePromiseAll,
SafePromiseRace,
Symbol,
Expand Down Expand Up @@ -62,6 +63,9 @@ const rootConcurrency = isTestRunner ? MathMax(cpus().length - 1, 1) : 1;
const kShouldAbort = Symbol('kShouldAbort');
const kRunHook = Symbol('kRunHook');
const kHookNames = ObjectSeal(['before', 'after', 'beforeEach', 'afterEach']);
const kUnwrapErrors = new SafeSet()
.add(kTestCodeFailure).add(kHookFailure)
.add('uncaughtException').add('unhandledRejection');


function stopTest(timeout, signal) {
Expand Down Expand Up @@ -727,9 +731,9 @@ module.exports = {
ItTest,
kCancelledByParent,
kDefaultIndent,
kHookFailure,
kSubtestsFailed,
kTestCodeFailure,
kUnwrapErrors,
Suite,
Test,
};
1 change: 1 addition & 0 deletions test/message/test_runner_describe_it.out
Expand Up @@ -418,6 +418,7 @@ not ok 49 - callback async throw
code: 'ERR_TEST_FAILURE'
stack: |-
*
*
...
# Subtest: callback async throw after done
ok 50 - callback async throw after done
Expand Down
12 changes: 12 additions & 0 deletions test/message/test_runner_output.js
Expand Up @@ -371,3 +371,15 @@ test('rejected thenable', () => {
},
};
});

test('unfinished test with uncaughtException', async () => {
await new Promise(() => {
setTimeout(() => { throw new Error('foo'); });
});
});

test('unfinished test with unhandledRejection', async () => {
await new Promise(() => {
setTimeout(() => Promise.reject(new Error('bar')));
});
});
33 changes: 29 additions & 4 deletions test/message/test_runner_output.out
Expand Up @@ -463,6 +463,7 @@ not ok 51 - callback async throw
code: 'ERR_TEST_FAILURE'
stack: |-
*
*
...
# Subtest: callback async throw after done
ok 52 - callback async throw after done
Expand Down Expand Up @@ -601,8 +602,32 @@ not ok 62 - rejected thenable
error: 'custom error'
code: 'ERR_TEST_FAILURE'
...
# Subtest: unfinished test with uncaughtException
not ok 63 - unfinished test with uncaughtException
---
duration_ms: *
failureType: 'uncaughtException'
error: 'foo'
code: 'ERR_TEST_FAILURE'
stack: |-
*
*
*
...
# Subtest: unfinished test with unhandledRejection
not ok 64 - unfinished test with unhandledRejection
---
duration_ms: *
failureType: 'unhandledRejection'
error: 'bar'
code: 'ERR_TEST_FAILURE'
stack: |-
*
*
*
...
# Subtest: invalid subtest fail
not ok 63 - invalid subtest fail
not ok 65 - invalid subtest fail
---
duration_ms: *
failureType: 'parentAlreadyFinished'
Expand All @@ -611,16 +636,16 @@ not ok 63 - invalid subtest fail
stack: |-
*
...
1..63
1..65
# Warning: Test "unhandled rejection - passes but warns" generated asynchronous activity after the test ended. This activity created the error "Error: rejected from unhandled rejection fail" and would have caused the test to fail, but instead triggered an unhandledRejection event.
# Warning: Test "async unhandled rejection - passes but warns" generated asynchronous activity after the test ended. This activity created the error "Error: rejected from async unhandled rejection fail" and would have caused the test to fail, but instead triggered an unhandledRejection event.
# Warning: Test "immediate throw - passes but warns" generated asynchronous activity after the test ended. This activity created the error "Error: thrown from immediate throw fail" and would have caused the test to fail, but instead triggered an uncaughtException event.
# Warning: Test "immediate reject - passes but warns" generated asynchronous activity after the test ended. This activity created the error "Error: rejected from immediate reject fail" and would have caused the test to fail, but instead triggered an unhandledRejection event.
# Warning: Test "callback called twice in different ticks" generated asynchronous activity after the test ended. This activity created the error "Error [ERR_TEST_FAILURE]: callback invoked multiple times" and would have caused the test to fail, but instead triggered an uncaughtException event.
# Warning: Test "callback async throw after done" generated asynchronous activity after the test ended. This activity created the error "Error: thrown from callback async throw after done" and would have caused the test to fail, but instead triggered an uncaughtException event.
# tests 63
# tests 65
# pass 27
# fail 19
# fail 21
# cancelled 2
# skipped 10
# todo 5
Expand Down

0 comments on commit 5ab3bc9

Please sign in to comment.