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‎

Lines changed: 17 additions & 8 deletions
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
constmyWarning=newError('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‎

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,26 +13,45 @@ function setupProcessWarnings(){
1313
consttrace=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-
vartoString=warning.toString;
19-
if(typeoftoString!=='function')
20-
toString=Error.prototype.toString;
21-
console.error(`${prefix}${toString.apply(warning)}`);
22+
consttoString=
23+
typeofwarning.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(typeofname==='function'){
30-
ctor=name;
31-
name='Warning';
36+
// process.emitWarning(str[, type[, code]][, ctor])
37+
process.emitWarning=function(warning,type,code,ctor){
38+
if(typeoftype==='function'){
39+
ctor=type;
40+
code=undefined;
41+
type='Warning';
3242
}
43+
if(typeofcode==='function'){
44+
ctor=code;
45+
code=undefined;
46+
}
47+
if(code!==undefined&&typeofcode!=='string')
48+
thrownewTypeError('\'code\' must be a String');
49+
if(type!==undefined&&typeoftype!=='string')
50+
thrownewTypeError('\'type\' must be a String');
3351
if(warning===undefined||typeofwarning==='string'){
3452
warning=newError(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(!(warninginstanceofError)){

‎test/parallel/test-process-emitwarning.js‎

Lines changed: 16 additions & 3 deletions
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
functionCustomWarning(){
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)