// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. // @ts-check /// /// /// /// /// import { primordials } from "ext:core/mod.js"; const { ArrayPrototypeSlice, Error, ErrorPrototype, ObjectDefineProperty, ObjectCreate, ObjectEntries, ObjectPrototypeIsPrototypeOf, ObjectSetPrototypeOf, Symbol, SymbolFor, } = primordials; import * as webidl from "ext:deno_webidl/00_webidl.js"; import { createFilteredInspectProxy } from "ext:deno_console/01_console.js"; const _name = Symbol("name"); const _message = Symbol("message"); const _code = Symbol("code"); const _error = Symbol("error"); // Defined in WebIDL 4.3. // https://webidl.spec.whatwg.org/#idl-DOMException const INDEX_SIZE_ERR = 1; const DOMSTRING_SIZE_ERR = 2; const HIERARCHY_REQUEST_ERR = 3; const WRONG_DOCUMENT_ERR = 4; const INVALID_CHARACTER_ERR = 5; const NO_DATA_ALLOWED_ERR = 6; const NO_MODIFICATION_ALLOWED_ERR = 7; const NOT_FOUND_ERR = 8; const NOT_SUPPORTED_ERR = 9; const INUSE_ATTRIBUTE_ERR = 10; const INVALID_STATE_ERR = 11; const SYNTAX_ERR = 12; const INVALID_MODIFICATION_ERR = 13; const NAMESPACE_ERR = 14; const INVALID_ACCESS_ERR = 15; const VALIDATION_ERR = 16; const TYPE_MISMATCH_ERR = 17; const SECURITY_ERR = 18; const NETWORK_ERR = 19; const ABORT_ERR = 20; const URL_MISMATCH_ERR = 21; const QUOTA_EXCEEDED_ERR = 22; const TIMEOUT_ERR = 23; const INVALID_NODE_TYPE_ERR = 24; const DATA_CLONE_ERR = 25; // Defined in WebIDL 2.8.1. // https://webidl.spec.whatwg.org/#dfn-error-names-table /** @type {Record} */ // the prototype should be null, to prevent user code from looking // up Object.prototype properties, such as "toString" const nameToCodeMapping = ObjectCreate(null, { IndexSizeError: { value: INDEX_SIZE_ERR }, HierarchyRequestError: { value: HIERARCHY_REQUEST_ERR }, WrongDocumentError: { value: WRONG_DOCUMENT_ERR }, InvalidCharacterError: { value: INVALID_CHARACTER_ERR }, NoModificationAllowedError: { value: NO_MODIFICATION_ALLOWED_ERR }, NotFoundError: { value: NOT_FOUND_ERR }, NotSupportedError: { value: NOT_SUPPORTED_ERR }, InUseAttributeError: { value: INUSE_ATTRIBUTE_ERR }, InvalidStateError: { value: INVALID_STATE_ERR }, SyntaxError: { value: SYNTAX_ERR }, InvalidModificationError: { value: INVALID_MODIFICATION_ERR }, NamespaceError: { value: NAMESPACE_ERR }, InvalidAccessError: { value: INVALID_ACCESS_ERR }, TypeMismatchError: { value: TYPE_MISMATCH_ERR }, SecurityError: { value: SECURITY_ERR }, NetworkError: { value: NETWORK_ERR }, AbortError: { value: ABORT_ERR }, URLMismatchError: { value: URL_MISMATCH_ERR }, QuotaExceededError: { value: QUOTA_EXCEEDED_ERR }, TimeoutError: { value: TIMEOUT_ERR }, InvalidNodeTypeError: { value: INVALID_NODE_TYPE_ERR }, DataCloneError: { value: DATA_CLONE_ERR }, }); // Defined in WebIDL 4.3. // https://webidl.spec.whatwg.org/#idl-DOMException class DOMException { [_message]; [_name]; [_code]; // https://webidl.spec.whatwg.org/#dom-domexception-domexception constructor(message = "", name = "Error") { message = webidl.converters.DOMString( message, "Failed to construct 'DOMException'", "Argument 1", ); name = webidl.converters.DOMString( name, "Failed to construct 'DOMException'", "Argument 2", ); const code = nameToCodeMapping[name] ?? 0; this[_message] = message; this[_name] = name; this[_code] = code; this[webidl.brand] = webidl.brand; this[_error] = new Error(message); this[_error].name = "DOMException"; } get message() { webidl.assertBranded(this, DOMExceptionPrototype); return this[_message]; } get name() { webidl.assertBranded(this, DOMExceptionPrototype); return this[_name]; } get code() { webidl.assertBranded(this, DOMExceptionPrototype); return this[_code]; } [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { if (ObjectPrototypeIsPrototypeOf(DOMExceptionPrototype, this)) { return this[_error].stack; } else { return inspect( createFilteredInspectProxy({ object: this, evaluate: false, keys: [ "message", "name", "code", ], }), inspectOptions, ); } } } ObjectDefineProperty(DOMException.prototype, "stack", { get() { return this[_error].stack; }, set(value) { this[_error].stack = value; }, configurable: true, }); // `DOMException` isn't a native error, so `Error.prepareStackTrace()` is // not called when accessing `.stack`, meaning our structured stack trace // hack doesn't apply. This patches it in. ObjectDefineProperty(DOMException.prototype, "__callSiteEvals", { get() { return ArrayPrototypeSlice(this[_error].__callSiteEvals, 1); }, configurable: true, }); ObjectSetPrototypeOf(DOMException.prototype, ErrorPrototype); webidl.configureInterface(DOMException); const DOMExceptionPrototype = DOMException.prototype; const entries = ObjectEntries({ INDEX_SIZE_ERR, DOMSTRING_SIZE_ERR, HIERARCHY_REQUEST_ERR, WRONG_DOCUMENT_ERR, INVALID_CHARACTER_ERR, NO_DATA_ALLOWED_ERR, NO_MODIFICATION_ALLOWED_ERR, NOT_FOUND_ERR, NOT_SUPPORTED_ERR, INUSE_ATTRIBUTE_ERR, INVALID_STATE_ERR, SYNTAX_ERR, INVALID_MODIFICATION_ERR, NAMESPACE_ERR, INVALID_ACCESS_ERR, VALIDATION_ERR, TYPE_MISMATCH_ERR, SECURITY_ERR, NETWORK_ERR, ABORT_ERR, URL_MISMATCH_ERR, QUOTA_EXCEEDED_ERR, TIMEOUT_ERR, INVALID_NODE_TYPE_ERR, DATA_CLONE_ERR, }); for (let i = 0; i < entries.length; ++i) { const { 0: key, 1: value } = entries[i]; const desc = { value, enumerable: true }; ObjectDefineProperty(DOMException, key, desc); ObjectDefineProperty(DOMException.prototype, key, desc); } export { DOMException, DOMExceptionPrototype };