Skip to content

Commit 5e1f32f

Browse files
committed
process: add optional code to warnings + type checking
Add the ability to assign an optional code to process warnings + add additional type checking to ensure that names and codes can only be strings. PR-URL: #10116 Reviewed-By: Michael Dawson <[email protected]> Reviewed-By: Michal Zasso <[email protected]> Reviewed-By: Fedor Indutny <[email protected]>
1 parent 60d77bd commit 5e1f32f

File tree

3 files changed

+63
-22
lines changed

3 files changed

+63
-22
lines changed

doc/api/process.md

+17-8
Original file line numberDiff line numberDiff line change
@@ -706,14 +706,15 @@ console.log(process.env.test);
706706
// => 1
707707
```
708708

709-
## process.emitWarning(warning[, name][, ctor])
709+
## process.emitWarning(warning[, type[, code]][, ctor])
710710
<!-- YAML
711711
added: v6.0.0
712712
-->
713713

714714
* `warning` {String | Error} The warning to emit.
715-
* `name` {String} When `warning` is a String, `name` is the name to use
716-
for the warning. Default: `Warning`.
715+
* `type` {String} When `warning` is a String, `type` is the name to use
716+
for the *type* of warning being emitted. Default: `Warning`.
717+
* `code` {String} A unique identifier for the warning instance being emitted.
717718
* `ctor` {Function} When `warning` is a String, `ctor` is an optional
718719
function used to limit the generated stack trace. Default
719720
`process.emitWarning`
@@ -729,11 +730,16 @@ process.emitWarning('Something happened!');
729730
```
730731

731732
```js
732-
// Emit a warning using a string and a name...
733+
// Emit a warning using a string and a type...
733734
process.emitWarning('Something Happened!', 'CustomWarning');
734735
// Emits: (node:56338) CustomWarning: Something Happened!
735736
```
736737

738+
```js
739+
process.emitWarning('Something happened!', 'CustomWarning', 'WARN001');
740+
// Emits: (node:56338) CustomWarning [WARN001]: Something Happened!
741+
```
742+
737743
In each of the previous examples, an `Error` object is generated internally by
738744
`process.emitWarning()` and passed through to the
739745
[`process.on('warning')`][process_warning] event.
@@ -742,21 +748,24 @@ In each of the previous examples, an `Error` object is generated internally by
742748
process.on('warning', (warning) => {
743749
console.warn(warning.name);
744750
console.warn(warning.message);
751+
console.warn(warning.code);
745752
console.warn(warning.stack);
746753
});
747754
```
748755

749756
If `warning` is passed as an `Error` object, it will be passed through to the
750-
`process.on('warning')` event handler unmodified (and the optional `name`
751-
and `ctor` arguments will be ignored):
757+
`process.on('warning')` event handler unmodified (and the optional `type`,
758+
`code` and `ctor` arguments will be ignored):
752759

753760
```js
754761
// Emit a warning using an Error object...
755762
const myWarning = new Error('Warning! Something happened!');
763+
// Use the Error name property to specify the type name
756764
myWarning.name = 'CustomWarning';
765+
myWarning.code = 'WARN001';
757766

758767
process.emitWarning(myWarning);
759-
// Emits: (node:56338) CustomWarning: Warning! Something Happened!
768+
// Emits: (node:56338) CustomWarning [WARN001]: Warning! Something Happened!
760769
```
761770

762771
A `TypeError` is thrown if `warning` is anything other than a string or `Error`
@@ -765,7 +774,7 @@ object.
765774
Note that while process warnings use `Error` objects, the process warning
766775
mechanism is **not** a replacement for normal error handling mechanisms.
767776

768-
The following additional handling is implemented if the warning `name` is
777+
The following additional handling is implemented if the warning `type` is
769778
`DeprecationWarning`:
770779

771780
* If the `--throw-deprecation` command-line flag is used, the deprecation

lib/internal/process/warning.js

+30-11
Original file line numberDiff line numberDiff line change
@@ -13,26 +13,45 @@ function setupProcessWarnings() {
1313
const trace = process.traceProcessWarnings ||
1414
(isDeprecation && process.traceDeprecation);
1515
if (trace && warning.stack) {
16-
console.error(`${prefix}${warning.stack}`);
16+
if (warning.code) {
17+
console.error(`${prefix}[${warning.code}] ${warning.stack}`);
18+
} else {
19+
console.error(`${prefix}${warning.stack}`);
20+
}
1721
} else {
18-
var toString = warning.toString;
19-
if (typeof toString !== 'function')
20-
toString = Error.prototype.toString;
21-
console.error(`${prefix}${toString.apply(warning)}`);
22+
const toString =
23+
typeof warning.toString === 'function' ?
24+
warning.toString : Error.prototype.toString;
25+
if (warning.code) {
26+
console.error(
27+
`${prefix}[${warning.code}] ${toString.apply(warning)}`);
28+
} else {
29+
console.error(`${prefix}${toString.apply(warning)}`);
30+
}
2231
}
2332
});
2433
}
2534

2635
// process.emitWarning(error)
27-
// process.emitWarning(str[, name][, ctor])
28-
process.emitWarning = function(warning, name, ctor) {
29-
if (typeof name === 'function') {
30-
ctor = name;
31-
name = 'Warning';
36+
// process.emitWarning(str[, type[, code]][, ctor])
37+
process.emitWarning = function(warning, type, code, ctor) {
38+
if (typeof type === 'function') {
39+
ctor = type;
40+
code = undefined;
41+
type = 'Warning';
3242
}
43+
if (typeof code === 'function') {
44+
ctor = code;
45+
code = undefined;
46+
}
47+
if (code !== undefined && typeof code !== 'string')
48+
throw new TypeError('\'code\' must be a String');
49+
if (type !== undefined && typeof type !== 'string')
50+
throw new TypeError('\'type\' must be a String');
3351
if (warning === undefined || typeof warning === 'string') {
3452
warning = new Error(warning);
35-
warning.name = name || 'Warning';
53+
warning.name = String(type || 'Warning');
54+
if (code !== undefined) warning.code = code;
3655
Error.captureStackTrace(warning, ctor || process.emitWarning);
3756
}
3857
if (!(warning instanceof Error)) {

test/parallel/test-process-emitwarning.js

+16-3
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,21 @@ const util = require('util');
99
process.on('warning', common.mustCall((warning) => {
1010
assert(warning);
1111
assert(/^(Warning|CustomWarning)/.test(warning.name));
12-
assert(warning.message, 'A Warning');
13-
}, 7));
12+
assert.strictEqual(warning.message, 'A Warning');
13+
if (warning.code) assert.strictEqual(warning.code, 'CODE001');
14+
}, 8));
1415

1516
process.emitWarning('A Warning');
1617
process.emitWarning('A Warning', 'CustomWarning');
1718
process.emitWarning('A Warning', CustomWarning);
1819
process.emitWarning('A Warning', 'CustomWarning', CustomWarning);
20+
process.emitWarning('A Warning', 'CustomWarning', 'CODE001');
1921

2022
function CustomWarning() {
2123
Error.call(this);
2224
this.name = 'CustomWarning';
2325
this.message = 'A Warning';
26+
this.code = 'CODE001';
2427
Error.captureStackTrace(this, CustomWarning);
2528
}
2629
util.inherits(CustomWarning, Error);
@@ -36,6 +39,16 @@ warningThrowToString.toString = function() {
3639
};
3740
process.emitWarning(warningThrowToString);
3841

39-
// TypeError is thrown on invalid output
42+
// TypeError is thrown on invalid input
4043
assert.throws(() => process.emitWarning(1), TypeError);
4144
assert.throws(() => process.emitWarning({}), TypeError);
45+
assert.throws(() => process.emitWarning(true), TypeError);
46+
assert.throws(() => process.emitWarning([]), TypeError);
47+
assert.throws(() => process.emitWarning('', {}), TypeError);
48+
assert.throws(() => process.emitWarning('', '', {}), TypeError);
49+
assert.throws(() => process.emitWarning('', 1), TypeError);
50+
assert.throws(() => process.emitWarning('', '', 1), TypeError);
51+
assert.throws(() => process.emitWarning('', true), TypeError);
52+
assert.throws(() => process.emitWarning('', '', true), TypeError);
53+
assert.throws(() => process.emitWarning('', []), TypeError);
54+
assert.throws(() => process.emitWarning('', '', []), TypeError);

0 commit comments

Comments
 (0)