Skip to content

Commit 690450d

Browse files
SimenBboujeepossum
authored andcommitted
print stack trace on calls to process.exit (#6714)
* print stack trace on calls to process.exit * link PR in changelog * guard exit handler against missing global process * moar guard * remove unnecessary newline
1 parent f66b74d commit 690450d

6 files changed

Lines changed: 74 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
## master
22

3+
### Features
4+
5+
- `[jest-runner]` print stack trace when `process.exit` is called from user code ([#6714](https://github.com/facebook/jest/pull/6714))
6+
37
### Fixes
48

59
- `[jest-snapshot` Mark snapshots as obsolete when moved to an inline snapshot ([#6773](https://github.com/facebook/jest/pull/6773))
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`prints stack trace pointing to process.exit call 1`] = `
4+
" ● process.exit called with \\"1\\"
5+
6+
> 1 | process.exit(1);
7+
| ^
8+
2 |
9+
3 | test('something', () => {
10+
4 | expect(true).toBe(true);
11+
12+
at Object.<anonymous> (__tests__/test.js:1:9)
13+
"
14+
`;

e2e/__tests__/process_exit.test.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/**
2+
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow
8+
*/
9+
'use strict';
10+
11+
const runJest = require('../runJest');
12+
13+
it('prints stack trace pointing to process.exit call', async () => {
14+
const {stderr} = await runJest('process-exit');
15+
16+
expect(stderr).toMatchSnapshot();
17+
});

e2e/process-exit/__tests__/test.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
process.exit(1);
2+
3+
test('something', () => {
4+
expect(true).toBe(true);
5+
});

e2e/process-exit/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"jest": {
3+
"testEnvironment": "node"
4+
}
5+
}

packages/jest-runner/src/run_test.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {
2525
import LeakDetector from 'jest-leak-detector';
2626
import {getTestEnvironment} from 'jest-config';
2727
import * as docblock from 'jest-docblock';
28+
import {formatExecError} from 'jest-message-util';
2829
import sourcemapSupport from 'source-map-support';
2930

3031
type RunTestInternalResult = {
@@ -145,6 +146,34 @@ async function runTestInternal(
145146
// For runtime errors
146147
sourcemapSupport.install(sourcemapOptions);
147148

149+
if (
150+
environment.global &&
151+
environment.global.process &&
152+
environment.global.process.exit
153+
) {
154+
const realExit = environment.global.process.exit;
155+
156+
environment.global.process.exit = function exit(...args) {
157+
const error = new Error(`process.exit called with "${args.join(', ')}"`);
158+
159+
if (Error.captureStackTrace) {
160+
Error.captureStackTrace(error, exit);
161+
}
162+
163+
const formattedError = formatExecError(
164+
error,
165+
config,
166+
{noStackTrace: false},
167+
undefined,
168+
true,
169+
);
170+
171+
process.stderr.write(formattedError);
172+
173+
return realExit(...args);
174+
};
175+
}
176+
148177
try {
149178
await environment.setup();
150179

0 commit comments

Comments
 (0)