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 0ee9c83

Browse filesBrowse files
authored
errors: improve performance of determine-specific-type
PR-URL: #49696 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
1 parent b903a71 commit 0ee9c83
Copy full SHA for 0ee9c83

File tree

Expand file treeCollapse file tree

5 files changed

+167
-17
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

5 files changed

+167
-17
lines changed
Open diff view settings
Collapse file
+58Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
5+
const bench = common.createBenchmark(main, {
6+
n: [1e6],
7+
v: [
8+
'() => 1n',
9+
'() => true',
10+
'() => false',
11+
'() => 2',
12+
'() => +0',
13+
'() => -0',
14+
'() => NaN',
15+
'() => Infinity',
16+
'() => ""',
17+
'() => "\'"',
18+
'() => Symbol("foo")',
19+
'() => function foo() {}',
20+
'() => null',
21+
'() => undefined',
22+
'() => new Array()',
23+
'() => new BigInt64Array()',
24+
'() => new BigUint64Array()',
25+
'() => new Int8Array()',
26+
'() => new Int16Array()',
27+
'() => new Int32Array()',
28+
'() => new Float32Array()',
29+
'() => new Float64Array()',
30+
'() => new Uint8Array()',
31+
'() => new Uint8ClampedArray()',
32+
'() => new Uint16Array()',
33+
'() => new Uint32Array()',
34+
'() => new Date()',
35+
'() => new Map()',
36+
'() => new WeakMap()',
37+
'() => new Object()',
38+
'() => Promise.resolve("foo")',
39+
'() => new Set()',
40+
'() => new WeakSet()',
41+
'() => ({ __proto__: null })',
42+
],
43+
}, {
44+
flags: ['--expose-internals'],
45+
});
46+
47+
function main({ n, v }) {
48+
const {
49+
determineSpecificType,
50+
} = require('internal/errors');
51+
52+
const value = eval(v)();
53+
54+
bench.start();
55+
for (let i = 0; i < n; ++i)
56+
determineSpecificType(value);
57+
bench.end(n);
58+
}
Collapse file

‎lib/internal/errors.js‎

Copy file name to clipboardExpand all lines: lib/internal/errors.js
+46-15Lines changed: 46 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ const {
4848
String,
4949
StringPrototypeEndsWith,
5050
StringPrototypeIncludes,
51+
StringPrototypeIndexOf,
5152
StringPrototypeSlice,
5253
StringPrototypeSplit,
5354
StringPrototypeStartsWith,
@@ -939,23 +940,53 @@ const genericNodeError = hideStackFrames(function genericNodeError(message, erro
939940
* @returns {string}
940941
*/
941942
function determineSpecificType(value) {
942-
if (value == null) {
943-
return '' + value;
943+
if (value === null) {
944+
return 'null';
945+
} else if (value === undefined) {
946+
return 'undefined';
944947
}
945-
if (typeof value === 'function' && value.name) {
946-
return `function ${value.name}`;
947-
}
948-
if (typeof value === 'object') {
949-
if (value.constructor?.name) {
950-
return `an instance of ${value.constructor.name}`;
951-
}
952-
return `${lazyInternalUtilInspect().inspect(value, { depth: -1 })}`;
953-
}
954-
let inspected = lazyInternalUtilInspect()
955-
.inspect(value, { colors: false });
956-
if (inspected.length > 28) { inspected = `${StringPrototypeSlice(inspected, 0, 25)}...`; }
957948

958-
return `type ${typeof value} (${inspected})`;
949+
const type = typeof value;
950+
951+
switch (type) {
952+
case 'bigint':
953+
return `type bigint (${value}n)`;
954+
case 'number':
955+
if (value === 0) {
956+
return 1 / value === -Infinity ? 'type number (-0)' : 'type number (0)';
957+
} else if (value !== value) { // eslint-disable-line no-self-compare
958+
return 'type number (NaN)';
959+
} else if (value === Infinity) {
960+
return 'type number (Infinity)';
961+
} else if (value === -Infinity) {
962+
return 'type number (-Infinity)';
963+
}
964+
return `type number (${value})`;
965+
case 'boolean':
966+
return value ? 'type boolean (true)' : 'type boolean (false)';
967+
case 'symbol':
968+
return `type symbol (${String(value)})`;
969+
case 'function':
970+
return `function ${value.name}`;
971+
case 'object':
972+
if (value.constructor && 'name' in value.constructor) {
973+
return `an instance of ${value.constructor.name}`;
974+
}
975+
return `${lazyInternalUtilInspect().inspect(value, { depth: -1 })}`;
976+
case 'string':
977+
value.length > 28 && (value = `${StringPrototypeSlice(value, 0, 25)}...`);
978+
if (StringPrototypeIndexOf(value, "'") === -1) {
979+
return `type string ('${value}')`;
980+
}
981+
return `type string (${JSONStringify(value)})`;
982+
default:
983+
value = lazyInternalUtilInspect().inspect(value, { colors: false });
984+
if (value.length > 28) {
985+
value = `${StringPrototypeSlice(value, 0, 25)}...`;
986+
}
987+
988+
return `type ${type} (${value})`;
989+
}
959990
}
960991

961992
/**
Collapse file

‎test/common/index.js‎

Copy file name to clipboardExpand all lines: test/common/index.js
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -816,7 +816,7 @@ function invalidArgTypeHelper(input) {
816816
if (input == null) {
817817
return ` Received ${input}`;
818818
}
819-
if (typeof input === 'function' && input.name) {
819+
if (typeof input === 'function') {
820820
return ` Received function ${input.name}`;
821821
}
822822
if (typeof input === 'object') {
Collapse file

‎test/parallel/test-error-value-type-detection.mjs‎

Copy file name to clipboardExpand all lines: test/parallel/test-error-value-type-detection.mjs
+61Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ strictEqual(
1212
'type bigint (1n)',
1313
);
1414

15+
strictEqual(
16+
determineSpecificType(true),
17+
'type boolean (true)',
18+
);
1519
strictEqual(
1620
determineSpecificType(false),
1721
'type boolean (false)',
@@ -42,6 +46,27 @@ strictEqual(
4246
"type string ('')",
4347
);
4448

49+
strictEqual(
50+
determineSpecificType(''),
51+
"type string ('')",
52+
);
53+
strictEqual(
54+
determineSpecificType("''"),
55+
"type string (\"''\")",
56+
);
57+
strictEqual(
58+
determineSpecificType('Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor'),
59+
"type string ('Lorem ipsum dolor sit ame...')",
60+
);
61+
strictEqual(
62+
determineSpecificType("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor'"),
63+
"type string ('Lorem ipsum dolor sit ame...')",
64+
);
65+
strictEqual(
66+
determineSpecificType("Lorem' ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor"),
67+
"type string (\"Lorem' ipsum dolor sit am...\")",
68+
);
69+
4570
strictEqual(
4671
determineSpecificType(Symbol('foo')),
4772
'type symbol (Symbol(foo))',
@@ -52,6 +77,38 @@ strictEqual(
5277
'function foo',
5378
);
5479

80+
const implicitlyNamed = function() {}; // eslint-disable-line func-style
81+
strictEqual(
82+
determineSpecificType(implicitlyNamed),
83+
'function implicitlyNamed',
84+
);
85+
strictEqual(
86+
determineSpecificType(() => {}),
87+
'function ',
88+
);
89+
function noName() {}
90+
delete noName.name;
91+
strictEqual(
92+
noName.name,
93+
'',
94+
);
95+
strictEqual(
96+
determineSpecificType(noName),
97+
'function ',
98+
);
99+
100+
function * generatorFn() {}
101+
strictEqual(
102+
determineSpecificType(generatorFn),
103+
'function generatorFn',
104+
);
105+
106+
async function asyncFn() {}
107+
strictEqual(
108+
determineSpecificType(asyncFn),
109+
'function asyncFn',
110+
);
111+
55112
strictEqual(
56113
determineSpecificType(null),
57114
'null',
@@ -134,6 +191,10 @@ strictEqual(
134191
determineSpecificType({}),
135192
'an instance of Object',
136193
);
194+
strictEqual(
195+
determineSpecificType(new Object()),
196+
'an instance of Object',
197+
);
137198

138199
strictEqual(
139200
determineSpecificType(Promise.resolve('foo')),
Collapse file

‎test/parallel/test-fs-readfile-error.js‎

Copy file name to clipboardExpand all lines: test/parallel/test-fs-readfile-error.js
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ assert.throws(
6161
{
6262
code: 'ERR_INVALID_ARG_TYPE',
6363
message: 'The "path" argument must be of type string or an instance of ' +
64-
'Buffer or URL. Received type function ([Function (anonymous)])',
64+
'Buffer or URL. Received function ',
6565
name: 'TypeError'
6666
}
6767
);

0 commit comments

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