1'use strict'; 2 3const { 4 ErrorCaptureStackTrace, 5 ErrorPrototype, 6 ObjectDefineProperties, 7 ObjectDefineProperty, 8 ObjectSetPrototypeOf, 9 SafeWeakMap, 10 SafeMap, 11 SafeSet, 12 SymbolToStringTag, 13 TypeError, 14} = primordials; 15 16function throwInvalidThisError(Base, type) { 17 const err = new Base(); 18 const key = 'ERR_INVALID_THIS'; 19 ObjectDefineProperties(err, { 20 message: { 21 __proto__: null, 22 value: `Value of "this" must be of ${type}`, 23 enumerable: false, 24 writable: true, 25 configurable: true, 26 }, 27 toString: { 28 __proto__: null, 29 value() { 30 return `${this.name} [${key}]: ${this.message}`; 31 }, 32 enumerable: false, 33 writable: true, 34 configurable: true, 35 }, 36 }); 37 err.code = key; 38 throw err; 39} 40 41const internalsMap = new SafeWeakMap(); 42const nameToCodeMap = new SafeMap(); 43 44// These were removed from the error names table. 45// See https://github.com/heycam/webidl/pull/946. 46const disusedNamesSet = new SafeSet() 47 .add('DOMStringSizeError') 48 .add('NoDataAllowedError') 49 .add('ValidationError'); 50 51class DOMException { 52 constructor(message = '', options = 'Error') { 53 ErrorCaptureStackTrace(this); 54 55 if (options && typeof options === 'object') { 56 const { name } = options; 57 internalsMap.set(this, { 58 message: `${message}`, 59 name: `${name}`, 60 }); 61 62 if ('cause' in options) { 63 ObjectDefineProperty(this, 'cause', { 64 __proto__: null, 65 value: options.cause, 66 configurable: true, 67 writable: true, 68 enumerable: false, 69 }); 70 } 71 } else { 72 internalsMap.set(this, { 73 message: `${message}`, 74 name: `${options}`, 75 }); 76 } 77 } 78 79 get name() { 80 const internals = internalsMap.get(this); 81 if (internals === undefined) { 82 throwInvalidThisError(TypeError, 'DOMException'); 83 } 84 return internals.name; 85 } 86 87 get message() { 88 const internals = internalsMap.get(this); 89 if (internals === undefined) { 90 throwInvalidThisError(TypeError, 'DOMException'); 91 } 92 return internals.message; 93 } 94 95 get code() { 96 const internals = internalsMap.get(this); 97 if (internals === undefined) { 98 throwInvalidThisError(TypeError, 'DOMException'); 99 } 100 101 if (disusedNamesSet.has(internals.name)) { 102 return 0; 103 } 104 105 const code = nameToCodeMap.get(internals.name); 106 return code === undefined ? 0 : code; 107 } 108} 109 110ObjectSetPrototypeOf(DOMException.prototype, ErrorPrototype); 111ObjectDefineProperties(DOMException.prototype, { 112 [SymbolToStringTag]: { __proto__: null, configurable: true, value: 'DOMException' }, 113 name: { __proto__: null, enumerable: true, configurable: true }, 114 message: { __proto__: null, enumerable: true, configurable: true }, 115 code: { __proto__: null, enumerable: true, configurable: true }, 116}); 117 118for (const { 0: name, 1: codeName, 2: value } of [ 119 ['IndexSizeError', 'INDEX_SIZE_ERR', 1], 120 ['DOMStringSizeError', 'DOMSTRING_SIZE_ERR', 2], 121 ['HierarchyRequestError', 'HIERARCHY_REQUEST_ERR', 3], 122 ['WrongDocumentError', 'WRONG_DOCUMENT_ERR', 4], 123 ['InvalidCharacterError', 'INVALID_CHARACTER_ERR', 5], 124 ['NoDataAllowedError', 'NO_DATA_ALLOWED_ERR', 6], 125 ['NoModificationAllowedError', 'NO_MODIFICATION_ALLOWED_ERR', 7], 126 ['NotFoundError', 'NOT_FOUND_ERR', 8], 127 ['NotSupportedError', 'NOT_SUPPORTED_ERR', 9], 128 ['InUseAttributeError', 'INUSE_ATTRIBUTE_ERR', 10], 129 ['InvalidStateError', 'INVALID_STATE_ERR', 11], 130 ['SyntaxError', 'SYNTAX_ERR', 12], 131 ['InvalidModificationError', 'INVALID_MODIFICATION_ERR', 13], 132 ['NamespaceError', 'NAMESPACE_ERR', 14], 133 ['InvalidAccessError', 'INVALID_ACCESS_ERR', 15], 134 ['ValidationError', 'VALIDATION_ERR', 16], 135 ['TypeMismatchError', 'TYPE_MISMATCH_ERR', 17], 136 ['SecurityError', 'SECURITY_ERR', 18], 137 ['NetworkError', 'NETWORK_ERR', 19], 138 ['AbortError', 'ABORT_ERR', 20], 139 ['URLMismatchError', 'URL_MISMATCH_ERR', 21], 140 ['QuotaExceededError', 'QUOTA_EXCEEDED_ERR', 22], 141 ['TimeoutError', 'TIMEOUT_ERR', 23], 142 ['InvalidNodeTypeError', 'INVALID_NODE_TYPE_ERR', 24], 143 ['DataCloneError', 'DATA_CLONE_ERR', 25], 144 // There are some more error names, but since they don't have codes assigned, 145 // we don't need to care about them. 146]) { 147 const desc = { enumerable: true, value }; 148 ObjectDefineProperty(DOMException, codeName, desc); 149 ObjectDefineProperty(DOMException.prototype, codeName, desc); 150 nameToCodeMap.set(name, value); 151} 152 153exports.DOMException = DOMException; 154