1
1
'use strict' ;
2
2
3
3
const {
4
- ErrorCaptureStackTrace ,
4
+ Error ,
5
5
ErrorPrototype,
6
6
ObjectDefineProperties,
7
7
ObjectDefineProperty,
@@ -60,20 +60,32 @@ const disusedNamesSet = new SafeSet()
60
60
. add ( 'NoDataAllowedError' )
61
61
. add ( 'ValidationError' ) ;
62
62
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
63
71
class DOMException {
64
72
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 ;
67
79
68
80
if ( options && typeof options === 'object' ) {
69
81
const { name } = options ;
70
- internalsMap . set ( this , {
82
+ internalsMap . set ( self , {
71
83
message : `${ message } ` ,
72
84
name : `${ name } ` ,
73
85
} ) ;
74
86
75
87
if ( 'cause' in options ) {
76
- ObjectDefineProperty ( this , 'cause' , {
88
+ ObjectDefineProperty ( self , 'cause' , {
77
89
__proto__ : null ,
78
90
value : options . cause ,
79
91
configurable : true ,
@@ -82,11 +94,14 @@ class DOMException {
82
94
} ) ;
83
95
}
84
96
} else {
85
- internalsMap . set ( this , {
97
+ internalsMap . set ( self , {
86
98
message : `${ message } ` ,
87
99
name : `${ options } ` ,
88
100
} ) ;
89
101
}
102
+ // Return the error object as the return override of the constructor.
103
+ // eslint-disable-next-line no-constructor-return
104
+ return self ;
90
105
}
91
106
92
107
[ messaging_clone_symbol ] ( ) {
@@ -142,8 +157,9 @@ class DOMException {
142
157
}
143
158
}
144
159
145
- ObjectSetPrototypeOf ( DOMException . prototype , ErrorPrototype ) ;
146
- ObjectDefineProperties ( DOMException . prototype , {
160
+ DOMExceptionPrototype = DOMException . prototype ;
161
+ ObjectSetPrototypeOf ( DOMExceptionPrototype , ErrorPrototype ) ;
162
+ ObjectDefineProperties ( DOMExceptionPrototype , {
147
163
[ SymbolToStringTag ] : { __proto__ : null , configurable : true , value : 'DOMException' } ,
148
164
name : { __proto__ : null , enumerable : true , configurable : true } ,
149
165
message : { __proto__ : null , enumerable : true , configurable : true } ,
@@ -181,7 +197,7 @@ for (const { 0: name, 1: codeName, 2: value } of [
181
197
] ) {
182
198
const desc = { enumerable : true , value } ;
183
199
ObjectDefineProperty ( DOMException , codeName , desc ) ;
184
- ObjectDefineProperty ( DOMException . prototype , codeName , desc ) ;
200
+ ObjectDefineProperty ( DOMExceptionPrototype , codeName , desc ) ;
185
201
nameToCodeMap . set ( name , value ) ;
186
202
}
187
203
0 commit comments