Skip to content

Commit 7793554

Browse files
SimenBcpojer
authored andcommitted
Always remove node internals from stacktraces (#4695)
* Always remove node internals from stacktraces * Update link to PR in changelog * Fix browser test * Remove weird next_tick trace just in integration tests * Rename some regexpes * Revert "Remove weird next_tick trace just in integration tests" This reverts commit f097ece. * Note code that can be delete when we drop support fo node 4
1 parent 291e836 commit 7793554

7 files changed

Lines changed: 113 additions & 16 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@
1010
* `[jest-editor-support]` Fix editor support test for node 4 ([#4640](https://github.com/facebook/jest/pull/4640))
1111
* `[jest-mock]` Support mocking constructor in `mockImplementationOnce` ([#4599](https://github.com/facebook/jest/pull/4599))
1212
* `[jest-runtime]` Fix manual user mocks not working with custom resolver ([#4489](https://github.com/facebook/jest/pull/4489))
13-
* `[jest-runtime]` Move `babel-core` to peer dependenies so it works with Babel 7 ([#4557](https://github.com/facebook/jest/pull/4557))
13+
* `[jest-runtime]` Move `babel-core` to peer dependencies so it works with Babel 7 ([#4557](https://github.com/facebook/jest/pull/4557))
1414
* `[jest-util]` Fix `runOnlyPendingTimers` for `setTimeout` inside `setImmediate` ([#4608](https://github.com/facebook/jest/pull/4608))
15+
* `[jest-message-util]` Always remove node internals from stacktraces ([#4695](https://github.com/facebook/jest/pull/4695))
1516

1617
### Features
1718
* `[jest-environment-*]` [**BREAKING**] Add Async Test Environment APIs, dispose is now teardown ([#4506](https://github.com/facebook/jest/pull/4506))

integration_tests/utils.js

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -156,16 +156,9 @@ const extractSummary = (stdout: string) => {
156156

157157
// different versions of Node print different stack traces. This function
158158
// unifies their output to make it possible to snapshot them.
159+
// TODO: Remove when we drop support for node 4
159160
const cleanupStackTrace = (output: string) => {
160-
return output
161-
.replace(/\n.*at.*timers\.js.*$/gm, '')
162-
.replace(/\n.*at.*assert\.js.*$/gm, '')
163-
.replace(/\n.*at.*node\.js.*$/gm, '')
164-
.replace(/\n.*at.*next_tick\.js.*$/gm, '')
165-
.replace(/\n.*at (new )?Promise \(<anonymous>\).*$/gm, '')
166-
.replace(/\n.*at <anonymous>.*$/gm, '')
167-
.replace(/\n.*at Generator.next \(<anonymous>\).*$/gm, '')
168-
.replace(/^.*at.*[\s][\(]?(\S*\:\d*\:\d*).*$/gm, ' at $1');
161+
return output.replace(/^.*at.*[\s][\(]?(\S*\:\d*\:\d*).*$/gm, ' at $1');
169162
};
170163

171164
module.exports = {

packages/jest-message-util/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"dependencies": {
1111
"chalk": "^2.0.1",
1212
"micromatch": "^2.3.11",
13-
"slash": "^1.0.0"
13+
"slash": "^1.0.0",
14+
"stack-utils": "^1.0.1"
1415
}
1516
}

packages/jest-message-util/src/__tests__/__snapshots__/messages.test.js.snap

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,23 @@ exports[`.formatExecError() 1`] = `
77
"
88
`;
99
10+
exports[`formatStackTrace should strip node internals 1`] = `
11+
"<bold><red> <bold>● <bold>Unix test</></>
12+
13+
14+
Expected value to be of type:
15+
\\"number\\"
16+
Received:
17+
\\"\\"
18+
type:
19+
\\"string\\"
20+
<dim> </>
21+
<dim> </>
22+
<dim> <dim>at Object.it (<dim>__tests__/test.js<dim>:8:14)<dim></>
23+
<dim> </>
24+
"
25+
`;
26+
1027
exports[`should exclude jasmine from stack trace for Unix paths. 1`] = `
1128
"<bold><red> <bold>● <bold>Unix test</></>
1229

packages/jest-message-util/src/__tests__/messages.test.js

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
'use strict';
1010

11-
const {formatResultsErrors, formatExecError} = require('../');
11+
const {formatResultsErrors, formatExecError} = require('..');
1212

1313
const unixStackTrace =
1414
` ` +
@@ -23,6 +23,27 @@ const unixStackTrace =
2323
at Object.<anonymous> (../jest-jasmine2/build/jasmine-pit.js:35:32)
2424
at attemptAsync (../jest-jasmine2/build/jasmine-2.4.1.js:1919:24)`;
2525

26+
const assertionStack =
27+
' ' +
28+
`
29+
Expected value to be of type:
30+
"number"
31+
Received:
32+
""
33+
type:
34+
"string"
35+
36+
at Object.it (__tests__/test.js:8:14)
37+
at Object.asyncFn (node_modules/jest-jasmine2/build/jasmine_async.js:124:345)
38+
at resolve (node_modules/jest-jasmine2/build/queue_runner.js:46:12)
39+
at Promise (<anonymous>)
40+
at mapper (node_modules/jest-jasmine2/build/queue_runner.js:34:499)
41+
at promise.then (node_modules/jest-jasmine2/build/queue_runner.js:74:39)
42+
at <anonymous>
43+
at process._tickCallback (internal/process/next_tick.js:188:7)
44+
at internal/process/next_tick.js:188:7
45+
`;
46+
2647
it('should exclude jasmine from stack trace for Unix paths.', () => {
2748
const messages = formatResultsErrors(
2849
[
@@ -62,3 +83,23 @@ it('.formatExecError()', () => {
6283

6384
expect(message).toMatchSnapshot();
6485
});
86+
87+
it('formatStackTrace should strip node internals', () => {
88+
const messages = formatResultsErrors(
89+
[
90+
{
91+
ancestorTitles: [],
92+
failureMessages: [assertionStack],
93+
title: 'Unix test',
94+
},
95+
],
96+
{
97+
rootDir: '',
98+
},
99+
{
100+
noStackTrace: false,
101+
},
102+
);
103+
104+
expect(messages).toMatchSnapshot();
105+
});

packages/jest-message-util/src/index.js

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,19 @@ import path from 'path';
1414
import chalk from 'chalk';
1515
import micromatch from 'micromatch';
1616
import slash from 'slash';
17+
import StackUtils from 'stack-utils';
18+
19+
let nodeInternals = [];
20+
21+
try {
22+
nodeInternals = StackUtils.nodeInternals()
23+
// this is to have the tests be the same in node 4 and node 6.
24+
// TODO: Remove when we drop support for node 4
25+
.concat(new RegExp('internal/process/next_tick.js'));
26+
} catch (e) {
27+
// `StackUtils.nodeInternals()` fails in browsers. We don't need to remove
28+
// node internals in the browser though, so no issue.
29+
}
1730

1831
type StackTraceConfig = {
1932
rootDir: string,
@@ -26,7 +39,10 @@ type StackTraceOptions = {
2639

2740
// filter for noisy stack trace lines
2841
const JASMINE_IGNORE = /^\s+at(?:(?:.*?vendor\/|jasmine\-)|\s+jasmine\.buildExpectationResult)/;
29-
const STACK_TRACE_IGNORE = /^\s+at.*?jest(-.*?)?(\/|\\)(build|node_modules|packages)(\/|\\)/;
42+
const JEST_INTERNALS_IGNORE = /^\s+at.*?jest(-.*?)?(\/|\\)(build|node_modules|packages)(\/|\\)/;
43+
const ANONYMOUS_FN_IGNORE = /^\s+at <anonymous>.*$/;
44+
const ANONYMOUS_PROMISE_IGNORE = /^\s+at (new )?Promise \(<anonymous>\).*$/;
45+
const ANONYMOUS_GENERATOR_IGNORE = /^\s+at Generator.next \(<anonymous>\).*$/;
3046
const TITLE_INDENT = ' ';
3147
const MESSAGE_INDENT = ' ';
3248
const STACK_INDENT = ' ';
@@ -106,10 +122,26 @@ const removeInternalStackEntries = (lines, options: StackTraceOptions) => {
106122
let pathCounter = 0;
107123

108124
return lines.filter(line => {
109-
const isPath = STACK_PATH_REGEXP.test(line);
110-
if (!isPath) {
125+
if (ANONYMOUS_FN_IGNORE.test(line)) {
126+
return false;
127+
}
128+
129+
if (ANONYMOUS_PROMISE_IGNORE.test(line)) {
130+
return false;
131+
}
132+
133+
if (ANONYMOUS_GENERATOR_IGNORE.test(line)) {
134+
return false;
135+
}
136+
137+
if (nodeInternals.some(internal => internal.test(line))) {
138+
return false;
139+
}
140+
141+
if (!STACK_PATH_REGEXP.test(line)) {
111142
return true;
112143
}
144+
113145
if (JASMINE_IGNORE.test(line)) {
114146
return false;
115147
}
@@ -118,7 +150,15 @@ const removeInternalStackEntries = (lines, options: StackTraceOptions) => {
118150
return true; // always keep the first line even if it's from Jest
119151
}
120152

121-
return !(STACK_TRACE_IGNORE.test(line) || options.noStackTrace);
153+
if (options.noStackTrace) {
154+
return false;
155+
}
156+
157+
if (JEST_INTERNALS_IGNORE.test(line)) {
158+
return false;
159+
}
160+
161+
return true;
122162
});
123163
};
124164

yarn.lock

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5444,6 +5444,10 @@ sshpk@^1.7.0:
54445444
jsbn "~0.1.0"
54455445
tweetnacl "~0.14.0"
54465446

5447+
stack-utils@^1.0.1:
5448+
version "1.0.1"
5449+
resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.1.tgz#d4f33ab54e8e38778b0ca5cfd3b3afb12db68620"
5450+
54475451
state-toggle@^1.0.0:
54485452
version "1.0.0"
54495453
resolved "https://registry.yarnpkg.com/state-toggle/-/state-toggle-1.0.0.tgz#d20f9a616bb4f0c3b98b91922d25b640aa2bc425"

0 commit comments

Comments
 (0)