Skip to content

Commit 0748160

Browse files
legendecastargos
authored andcommitted
lib: fix DOMException subclass support
PR-URL: #59680 Reviewed-By: Matthew Aitken <maitken033380023@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Jordan Harband <ljharb@gmail.com>
1 parent bda32af commit 0748160

File tree

2 files changed

+58
-3
lines changed

2 files changed

+58
-3
lines changed

lib/internal/per_context/domexception.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ const disusedNamesSet = new SafeSet()
6060
.add('NoDataAllowedError')
6161
.add('ValidationError');
6262

63-
let DOMExceptionPrototype;
6463
// The DOMException WebIDL interface defines that:
6564
// - ObjectGetPrototypeOf(DOMException) === Function.
6665
// - ObjectGetPrototypeOf(DOMException.prototype) === Error.prototype.
@@ -75,7 +74,8 @@ class DOMException {
7574
// internal slot.
7675
// eslint-disable-next-line no-restricted-syntax
7776
const self = new Error();
78-
ObjectSetPrototypeOf(self, DOMExceptionPrototype);
77+
// Use `new.target.prototype` to support DOMException subclasses.
78+
ObjectSetPrototypeOf(self, new.target.prototype);
7979
self[transfer_mode_private_symbol] = kCloneable;
8080

8181
if (options && typeof options === 'object') {
@@ -158,7 +158,7 @@ class DOMException {
158158
}
159159
}
160160

161-
DOMExceptionPrototype = DOMException.prototype;
161+
const DOMExceptionPrototype = DOMException.prototype;
162162
ObjectSetPrototypeOf(DOMExceptionPrototype, ErrorPrototype);
163163
ObjectDefineProperties(DOMExceptionPrototype, {
164164
[SymbolToStringTag]: { __proto__: null, configurable: true, value: 'DOMException' },
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
'use strict';
2+
3+
require('../common');
4+
const assert = require('assert');
5+
6+
class MyDOMException extends DOMException {
7+
ownProp;
8+
#reason;
9+
10+
constructor() {
11+
super('my message', 'NotFoundError');
12+
this.ownProp = 'bar';
13+
this.#reason = 'hello';
14+
}
15+
16+
get reason() {
17+
return this.#reason;
18+
}
19+
}
20+
21+
const myException = new MyDOMException();
22+
// Verifies the prototype chain
23+
assert(myException instanceof MyDOMException);
24+
assert(myException instanceof DOMException);
25+
assert(myException instanceof Error);
26+
// Verifies [[ErrorData]]
27+
assert(Error.isError(myException));
28+
29+
// Verifies subclass properties
30+
assert(Object.hasOwn(myException, 'ownProp'));
31+
assert(!Object.hasOwn(myException, 'reason'));
32+
assert.strictEqual(myException.reason, 'hello');
33+
34+
// Verifies error properties
35+
assert.strictEqual(myException.name, 'NotFoundError');
36+
assert.strictEqual(myException.code, 8);
37+
assert.strictEqual(myException.message, 'my message');
38+
assert.strictEqual(typeof myException.stack, 'string');
39+
40+
// Verify structuredClone only copies known error properties.
41+
const cloned = structuredClone(myException);
42+
assert(!(cloned instanceof MyDOMException));
43+
assert(cloned instanceof DOMException);
44+
assert(cloned instanceof Error);
45+
assert(Error.isError(cloned));
46+
47+
// Verify custom properties
48+
assert(!Object.hasOwn(cloned, 'ownProp'));
49+
assert.strictEqual(cloned.reason, undefined);
50+
51+
// Verify cloned error properties
52+
assert.strictEqual(cloned.name, 'NotFoundError');
53+
assert.strictEqual(cloned.code, 8);
54+
assert.strictEqual(cloned.message, 'my message');
55+
assert.strictEqual(cloned.stack, myException.stack);

0 commit comments

Comments
 (0)