Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit ada2d05

Browse filesBrowse files
authored
process: runtime deprecate coercion to integer in process.exit()
This is a follow up of doc-only deprecation #43738. Signed-off-by: Daeyeon Jeong daeyeon.dev@gmail.com PR-URL: #44711 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com> Reviewed-By: Darshan Sen <raisinten@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 24d255f commit ada2d05
Copy full SHA for ada2d05

File tree

Expand file treeCollapse file tree

6 files changed

+171
-5
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

6 files changed

+171
-5
lines changed
Open diff view settings
Collapse file

‎doc/api/deprecations.md‎

Copy file name to clipboardExpand all lines: doc/api/deprecations.md
+4-1Lines changed: 4 additions & 1 deletion
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -3175,6 +3175,9 @@ thing instead.
31753175

31763176
<!-- YAML
31773177
changes:
3178+
- version: REPLACEME
3179+
pr-url: https://github.com/nodejs/node/pull/44711
3180+
description: Runtime deprecation.
31783181
- version: v18.10.0
31793182
pr-url: https://github.com/nodejs/node/pull/44714
31803183
description: Documentation-only deprecation of `process.exitCode` integer
@@ -3187,7 +3190,7 @@ changes:
31873190
coercion.
31883191
-->
31893192

3190-
Type: Documentation-only
3193+
Type: Runtime
31913194

31923195
Values other than `undefined`, `null`, integer numbers, and integer strings
31933196
(e.g., `'1'`) are deprecated as value for the `code` parameter in
Collapse file

‎lib/internal/bootstrap/node.js‎

Copy file name to clipboardExpand all lines: lib/internal/bootstrap/node.js
+25Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,31 @@ process.domain = null;
102102
}
103103
process._exiting = false;
104104

105+
{
106+
const warnIntegerCoercionDeprecation = deprecate(
107+
() => {},
108+
'Implicit coercion to integer for exit code is deprecated.',
109+
'DEP0164'
110+
);
111+
112+
let exitCode;
113+
114+
ObjectDefineProperty(process, 'exitCode', {
115+
__proto__: null,
116+
get() {
117+
return exitCode;
118+
},
119+
set(code) {
120+
if (perThreadSetup.isDeprecatedExitCode(code)) {
121+
warnIntegerCoercionDeprecation();
122+
}
123+
exitCode = code;
124+
},
125+
enumerable: true,
126+
configurable: false,
127+
});
128+
}
129+
105130
// process.config is serialized config.gypi
106131
const nativeModule = internalBinding('builtins');
107132

Collapse file

‎lib/internal/process/per_thread.js‎

Copy file name to clipboardExpand all lines: lib/internal/process/per_thread.js
+35Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ const {
1313
ArrayPrototypeSplice,
1414
BigUint64Array,
1515
Float64Array,
16+
Number,
17+
NumberIsInteger,
1618
NumberMAX_SAFE_INTEGER,
19+
NumberMIN_SAFE_INTEGER,
1720
ObjectFreeze,
1821
ObjectDefineProperty,
1922
ReflectApply,
@@ -180,9 +183,23 @@ function wrapProcessMethods(binding) {
180183

181184
memoryUsage.rss = rss;
182185

186+
const { deprecate } = require('internal/util');
187+
const warnIntegerCoercionDeprecationSync = deprecate(
188+
() => {},
189+
'Implicit coercion to integer for exit code is deprecated.',
190+
'DEP0164',
191+
true
192+
);
193+
183194
function exit(code) {
184195
process.off('exit', handleProcessExit);
185196

197+
if (isDeprecatedExitCode(code)) {
198+
// Emit the deprecation warning synchronously since deprecation warning is
199+
// generally emitted in a next tick but we have no next tick timing here.
200+
warnIntegerCoercionDeprecationSync();
201+
}
202+
186203
if (code || code === 0)
187204
process.exitCode = code;
188205

@@ -407,6 +424,23 @@ function toggleTraceCategoryState(asyncHooksEnabled) {
407424
}
408425
}
409426

427+
function isDeprecatedExitCode(code) {
428+
if (code !== null && code !== undefined) {
429+
const value =
430+
typeof code === 'string' && code !== '' ? Number(code) : code;
431+
// Check if the value is an integer.
432+
if (
433+
typeof value !== 'number' ||
434+
!NumberIsInteger(value) ||
435+
value < NumberMIN_SAFE_INTEGER ||
436+
value > NumberMAX_SAFE_INTEGER
437+
) {
438+
return true;
439+
}
440+
}
441+
return false;
442+
}
443+
410444
module.exports = {
411445
toggleTraceCategoryState,
412446
assert,
@@ -415,4 +449,5 @@ module.exports = {
415449
hrtime,
416450
hrtimeBigInt,
417451
refreshHrtimeBuffer,
452+
isDeprecatedExitCode,
418453
};
Collapse file

‎lib/internal/process/warning.js‎

Copy file name to clipboardExpand all lines: lib/internal/process/warning.js
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,8 +166,8 @@ function emitWarning(warning, type, code, ctor) {
166166
process.nextTick(doEmitWarning, warning);
167167
}
168168

169-
function emitWarningSync(warning) {
170-
process.emit('warning', createWarningObject(warning));
169+
function emitWarningSync(warning, type, code, ctor) {
170+
process.emit('warning', createWarningObject(warning, type, code, ctor));
171171
}
172172

173173
function createWarningObject(warning, type, code, ctor, detail) {
Collapse file

‎lib/internal/util.js‎

Copy file name to clipboardExpand all lines: lib/internal/util.js
+5-2Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ let validateString;
9696
// Mark that a method should not be used.
9797
// Returns a modified function which warns once by default.
9898
// If --no-deprecation is set, then it is a no-op.
99-
function deprecate(fn, msg, code) {
99+
function deprecate(fn, msg, code, useEmitSync) {
100100
if (process.noDeprecation === true) {
101101
return fn;
102102
}
@@ -114,7 +114,10 @@ function deprecate(fn, msg, code) {
114114
warned = true;
115115
if (code !== undefined) {
116116
if (!codesWarned.has(code)) {
117-
process.emitWarning(msg, 'DeprecationWarning', code, deprecated);
117+
const emitWarning = useEmitSync ?
118+
require('internal/process/warning').emitWarningSync :
119+
process.emitWarning;
120+
emitWarning(msg, 'DeprecationWarning', code, deprecated);
118121
codesWarned.add(code);
119122
}
120123
} else {
Collapse file
+100Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
'use strict';
2+
3+
require('../common');
4+
5+
const deprecated = [
6+
{
7+
code: '',
8+
expected: 0,
9+
},
10+
{
11+
code: '1 one',
12+
expected: 0,
13+
},
14+
{
15+
code: 'two',
16+
expected: 0,
17+
},
18+
{
19+
code: {},
20+
expected: 0,
21+
},
22+
{
23+
code: [],
24+
expected: 0,
25+
},
26+
{
27+
code: true,
28+
expected: 1,
29+
},
30+
{
31+
code: false,
32+
expected: 0,
33+
},
34+
{
35+
code: 2n,
36+
expected: 0,
37+
expected_useProcessExitCode: 1,
38+
},
39+
{
40+
code: 2.1,
41+
expected: 2,
42+
},
43+
{
44+
code: Infinity,
45+
expected: 0,
46+
},
47+
{
48+
code: NaN,
49+
expected: 0,
50+
},
51+
];
52+
const args = deprecated;
53+
54+
if (process.argv[2] === undefined) {
55+
const { spawnSync } = require('node:child_process');
56+
const { inspect, debuglog } = require('node:util');
57+
const { strictEqual } = require('node:assert');
58+
59+
const debug = debuglog('test');
60+
const node = process.execPath;
61+
const test = (index, useProcessExitCode) => {
62+
const { status: code, stderr } = spawnSync(node, [
63+
__filename,
64+
index,
65+
useProcessExitCode,
66+
]);
67+
debug(`actual: ${code}, ${inspect(args[index])} ${!!useProcessExitCode}`);
68+
debug(`${stderr}`);
69+
70+
const expected =
71+
useProcessExitCode && args[index].expected_useProcessExitCode ?
72+
args[index].expected_useProcessExitCode :
73+
args[index].expected;
74+
75+
strictEqual(code, expected, `actual: ${code}, ${inspect(args[index])}`);
76+
strictEqual(
77+
['[DEP0164]'].some((pattern) => stderr.includes(pattern)),
78+
true
79+
);
80+
};
81+
82+
for (const index of args.keys()) {
83+
// Check `process.exit([code])`
84+
test(index);
85+
// Check exit with `process.exitCode`
86+
test(index, true);
87+
}
88+
} else {
89+
const index = parseInt(process.argv[2]);
90+
const useProcessExitCode = process.argv[3] !== 'undefined';
91+
if (Number.isNaN(index)) {
92+
return process.exit(100);
93+
}
94+
95+
if (useProcessExitCode) {
96+
process.exitCode = args[index].code;
97+
} else {
98+
process.exit(args[index].code);
99+
}
100+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.