Skip to content

Commit 40c22d3

Browse files
lib: make domexception a native error
Co-Authored-By: Kenta Moriuchi <[email protected]>
1 parent 5457443 commit 40c22d3

File tree

2 files changed

+26
-19
lines changed

2 files changed

+26
-19
lines changed

lib/internal/per_context/domexception.js

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict';
22

33
const {
4-
ErrorCaptureStackTrace,
4+
Error,
55
ErrorPrototype,
66
ObjectDefineProperties,
77
ObjectDefineProperty,
@@ -60,20 +60,32 @@ const disusedNamesSet = new SafeSet()
6060
.add('NoDataAllowedError')
6161
.add('ValidationError');
6262

63+
let DOMExceptionPrototype;
64+
// The DOMException WebIDL interface defines that:
65+
// - ObjectGetPrototypeOf(DOMException) === Function.
66+
// - ObjectGetPrototypeOf(DOMException.prototype) === Error.prototype.
67+
// Thus, we can not simply use the pattern of `class DOMException extends Error` and call
68+
// `super()` to construct an object. The `super` in `super()` call in the constructor will
69+
// resolved to `Function`, instead of `Error`.
70+
// Ref: https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-getsuperconstructor
6371
class DOMException {
6472
constructor(message = '', options = 'Error') {
65-
this[transfer_mode_private_symbol] = kCloneable;
66-
ErrorCaptureStackTrace(this);
73+
// Invokes the Error constructor to create an object with the [[ErrorData]]
74+
// internal slot.
75+
// eslint-disable-next-line no-restricted-syntax
76+
const self = new Error();
77+
ObjectSetPrototypeOf(self, DOMExceptionPrototype);
78+
self[transfer_mode_private_symbol] = kCloneable;
6779

6880
if (options && typeof options === 'object') {
6981
const { name } = options;
70-
internalsMap.set(this, {
82+
internalsMap.set(self, {
7183
message: `${message}`,
7284
name: `${name}`,
7385
});
7486

7587
if ('cause' in options) {
76-
ObjectDefineProperty(this, 'cause', {
88+
ObjectDefineProperty(self, 'cause', {
7789
__proto__: null,
7890
value: options.cause,
7991
configurable: true,
@@ -82,11 +94,14 @@ class DOMException {
8294
});
8395
}
8496
} else {
85-
internalsMap.set(this, {
97+
internalsMap.set(self, {
8698
message: `${message}`,
8799
name: `${options}`,
88100
});
89101
}
102+
// Return the error object as the return override of the constructor.
103+
// eslint-disable-next-line no-constructor-return
104+
return self;
90105
}
91106

92107
[messaging_clone_symbol]() {
@@ -142,8 +157,9 @@ class DOMException {
142157
}
143158
}
144159

145-
ObjectSetPrototypeOf(DOMException.prototype, ErrorPrototype);
146-
ObjectDefineProperties(DOMException.prototype, {
160+
DOMExceptionPrototype = DOMException.prototype;
161+
ObjectSetPrototypeOf(DOMExceptionPrototype, ErrorPrototype);
162+
ObjectDefineProperties(DOMExceptionPrototype, {
147163
[SymbolToStringTag]: { __proto__: null, configurable: true, value: 'DOMException' },
148164
name: { __proto__: null, enumerable: true, configurable: true },
149165
message: { __proto__: null, enumerable: true, configurable: true },
@@ -181,7 +197,7 @@ for (const { 0: name, 1: codeName, 2: value } of [
181197
]) {
182198
const desc = { enumerable: true, value };
183199
ObjectDefineProperty(DOMException, codeName, desc);
184-
ObjectDefineProperty(DOMException.prototype, codeName, desc);
200+
ObjectDefineProperty(DOMExceptionPrototype, codeName, desc);
185201
nameToCodeMap.set(name, value);
186202
}
187203

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1 @@
1-
{
2-
"DOMException-is-error.any.js": {
3-
"fail": {
4-
"note": "https://github.com/nodejs/node/issues/56497",
5-
"expected": [
6-
"DOMException-is-error"
7-
]
8-
}
9-
}
10-
}
1+
{}

0 commit comments

Comments
 (0)