mirror of https://github.com/nodejs/node.git
process: runtime deprecate coercion to integer in `process.exit()`
This is a follow up of doc-only deprecation https://github.com/nodejs/node/pull/43738. Signed-off-by: Daeyeon Jeong daeyeon.dev@gmail.com PR-URL: https://github.com/nodejs/node/pull/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>
This commit is contained in:
parent
24d255fe69
commit
ada2d053ae
|
@ -3175,6 +3175,9 @@ thing instead.
|
||||||
|
|
||||||
<!-- YAML
|
<!-- YAML
|
||||||
changes:
|
changes:
|
||||||
|
- version: REPLACEME
|
||||||
|
pr-url: https://github.com/nodejs/node/pull/44711
|
||||||
|
description: Runtime deprecation.
|
||||||
- version: v18.10.0
|
- version: v18.10.0
|
||||||
pr-url: https://github.com/nodejs/node/pull/44714
|
pr-url: https://github.com/nodejs/node/pull/44714
|
||||||
description: Documentation-only deprecation of `process.exitCode` integer
|
description: Documentation-only deprecation of `process.exitCode` integer
|
||||||
|
@ -3187,7 +3190,7 @@ changes:
|
||||||
coercion.
|
coercion.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
Type: Documentation-only
|
Type: Runtime
|
||||||
|
|
||||||
Values other than `undefined`, `null`, integer numbers, and integer strings
|
Values other than `undefined`, `null`, integer numbers, and integer strings
|
||||||
(e.g., `'1'`) are deprecated as value for the `code` parameter in
|
(e.g., `'1'`) are deprecated as value for the `code` parameter in
|
||||||
|
|
|
@ -102,6 +102,31 @@ process.domain = null;
|
||||||
}
|
}
|
||||||
process._exiting = false;
|
process._exiting = false;
|
||||||
|
|
||||||
|
{
|
||||||
|
const warnIntegerCoercionDeprecation = deprecate(
|
||||||
|
() => {},
|
||||||
|
'Implicit coercion to integer for exit code is deprecated.',
|
||||||
|
'DEP0164'
|
||||||
|
);
|
||||||
|
|
||||||
|
let exitCode;
|
||||||
|
|
||||||
|
ObjectDefineProperty(process, 'exitCode', {
|
||||||
|
__proto__: null,
|
||||||
|
get() {
|
||||||
|
return exitCode;
|
||||||
|
},
|
||||||
|
set(code) {
|
||||||
|
if (perThreadSetup.isDeprecatedExitCode(code)) {
|
||||||
|
warnIntegerCoercionDeprecation();
|
||||||
|
}
|
||||||
|
exitCode = code;
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// process.config is serialized config.gypi
|
// process.config is serialized config.gypi
|
||||||
const nativeModule = internalBinding('builtins');
|
const nativeModule = internalBinding('builtins');
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,10 @@ const {
|
||||||
ArrayPrototypeSplice,
|
ArrayPrototypeSplice,
|
||||||
BigUint64Array,
|
BigUint64Array,
|
||||||
Float64Array,
|
Float64Array,
|
||||||
|
Number,
|
||||||
|
NumberIsInteger,
|
||||||
NumberMAX_SAFE_INTEGER,
|
NumberMAX_SAFE_INTEGER,
|
||||||
|
NumberMIN_SAFE_INTEGER,
|
||||||
ObjectFreeze,
|
ObjectFreeze,
|
||||||
ObjectDefineProperty,
|
ObjectDefineProperty,
|
||||||
ReflectApply,
|
ReflectApply,
|
||||||
|
@ -180,9 +183,23 @@ function wrapProcessMethods(binding) {
|
||||||
|
|
||||||
memoryUsage.rss = rss;
|
memoryUsage.rss = rss;
|
||||||
|
|
||||||
|
const { deprecate } = require('internal/util');
|
||||||
|
const warnIntegerCoercionDeprecationSync = deprecate(
|
||||||
|
() => {},
|
||||||
|
'Implicit coercion to integer for exit code is deprecated.',
|
||||||
|
'DEP0164',
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
function exit(code) {
|
function exit(code) {
|
||||||
process.off('exit', handleProcessExit);
|
process.off('exit', handleProcessExit);
|
||||||
|
|
||||||
|
if (isDeprecatedExitCode(code)) {
|
||||||
|
// Emit the deprecation warning synchronously since deprecation warning is
|
||||||
|
// generally emitted in a next tick but we have no next tick timing here.
|
||||||
|
warnIntegerCoercionDeprecationSync();
|
||||||
|
}
|
||||||
|
|
||||||
if (code || code === 0)
|
if (code || code === 0)
|
||||||
process.exitCode = code;
|
process.exitCode = code;
|
||||||
|
|
||||||
|
@ -407,6 +424,23 @@ function toggleTraceCategoryState(asyncHooksEnabled) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isDeprecatedExitCode(code) {
|
||||||
|
if (code !== null && code !== undefined) {
|
||||||
|
const value =
|
||||||
|
typeof code === 'string' && code !== '' ? Number(code) : code;
|
||||||
|
// Check if the value is an integer.
|
||||||
|
if (
|
||||||
|
typeof value !== 'number' ||
|
||||||
|
!NumberIsInteger(value) ||
|
||||||
|
value < NumberMIN_SAFE_INTEGER ||
|
||||||
|
value > NumberMAX_SAFE_INTEGER
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
toggleTraceCategoryState,
|
toggleTraceCategoryState,
|
||||||
assert,
|
assert,
|
||||||
|
@ -415,4 +449,5 @@ module.exports = {
|
||||||
hrtime,
|
hrtime,
|
||||||
hrtimeBigInt,
|
hrtimeBigInt,
|
||||||
refreshHrtimeBuffer,
|
refreshHrtimeBuffer,
|
||||||
|
isDeprecatedExitCode,
|
||||||
};
|
};
|
||||||
|
|
|
@ -166,8 +166,8 @@ function emitWarning(warning, type, code, ctor) {
|
||||||
process.nextTick(doEmitWarning, warning);
|
process.nextTick(doEmitWarning, warning);
|
||||||
}
|
}
|
||||||
|
|
||||||
function emitWarningSync(warning) {
|
function emitWarningSync(warning, type, code, ctor) {
|
||||||
process.emit('warning', createWarningObject(warning));
|
process.emit('warning', createWarningObject(warning, type, code, ctor));
|
||||||
}
|
}
|
||||||
|
|
||||||
function createWarningObject(warning, type, code, ctor, detail) {
|
function createWarningObject(warning, type, code, ctor, detail) {
|
||||||
|
|
|
@ -96,7 +96,7 @@ let validateString;
|
||||||
// Mark that a method should not be used.
|
// Mark that a method should not be used.
|
||||||
// Returns a modified function which warns once by default.
|
// Returns a modified function which warns once by default.
|
||||||
// If --no-deprecation is set, then it is a no-op.
|
// If --no-deprecation is set, then it is a no-op.
|
||||||
function deprecate(fn, msg, code) {
|
function deprecate(fn, msg, code, useEmitSync) {
|
||||||
if (process.noDeprecation === true) {
|
if (process.noDeprecation === true) {
|
||||||
return fn;
|
return fn;
|
||||||
}
|
}
|
||||||
|
@ -114,7 +114,10 @@ function deprecate(fn, msg, code) {
|
||||||
warned = true;
|
warned = true;
|
||||||
if (code !== undefined) {
|
if (code !== undefined) {
|
||||||
if (!codesWarned.has(code)) {
|
if (!codesWarned.has(code)) {
|
||||||
process.emitWarning(msg, 'DeprecationWarning', code, deprecated);
|
const emitWarning = useEmitSync ?
|
||||||
|
require('internal/process/warning').emitWarningSync :
|
||||||
|
process.emitWarning;
|
||||||
|
emitWarning(msg, 'DeprecationWarning', code, deprecated);
|
||||||
codesWarned.add(code);
|
codesWarned.add(code);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
require('../common');
|
||||||
|
|
||||||
|
const deprecated = [
|
||||||
|
{
|
||||||
|
code: '',
|
||||||
|
expected: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: '1 one',
|
||||||
|
expected: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 'two',
|
||||||
|
expected: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: {},
|
||||||
|
expected: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: [],
|
||||||
|
expected: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: true,
|
||||||
|
expected: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: false,
|
||||||
|
expected: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 2n,
|
||||||
|
expected: 0,
|
||||||
|
expected_useProcessExitCode: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 2.1,
|
||||||
|
expected: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: Infinity,
|
||||||
|
expected: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: NaN,
|
||||||
|
expected: 0,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const args = deprecated;
|
||||||
|
|
||||||
|
if (process.argv[2] === undefined) {
|
||||||
|
const { spawnSync } = require('node:child_process');
|
||||||
|
const { inspect, debuglog } = require('node:util');
|
||||||
|
const { strictEqual } = require('node:assert');
|
||||||
|
|
||||||
|
const debug = debuglog('test');
|
||||||
|
const node = process.execPath;
|
||||||
|
const test = (index, useProcessExitCode) => {
|
||||||
|
const { status: code, stderr } = spawnSync(node, [
|
||||||
|
__filename,
|
||||||
|
index,
|
||||||
|
useProcessExitCode,
|
||||||
|
]);
|
||||||
|
debug(`actual: ${code}, ${inspect(args[index])} ${!!useProcessExitCode}`);
|
||||||
|
debug(`${stderr}`);
|
||||||
|
|
||||||
|
const expected =
|
||||||
|
useProcessExitCode && args[index].expected_useProcessExitCode ?
|
||||||
|
args[index].expected_useProcessExitCode :
|
||||||
|
args[index].expected;
|
||||||
|
|
||||||
|
strictEqual(code, expected, `actual: ${code}, ${inspect(args[index])}`);
|
||||||
|
strictEqual(
|
||||||
|
['[DEP0164]'].some((pattern) => stderr.includes(pattern)),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const index of args.keys()) {
|
||||||
|
// Check `process.exit([code])`
|
||||||
|
test(index);
|
||||||
|
// Check exit with `process.exitCode`
|
||||||
|
test(index, true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const index = parseInt(process.argv[2]);
|
||||||
|
const useProcessExitCode = process.argv[3] !== 'undefined';
|
||||||
|
if (Number.isNaN(index)) {
|
||||||
|
return process.exit(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (useProcessExitCode) {
|
||||||
|
process.exitCode = args[index].code;
|
||||||
|
} else {
|
||||||
|
process.exit(args[index].code);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue