mirror of
https://github.com/denoland/deno.git
synced 2024-11-21 15:04:11 -05:00
fix(ext/web): align DOMException better with spec (#15097)
This commit is contained in:
parent
2b1f145c3e
commit
b8e1250500
2 changed files with 70 additions and 39 deletions
|
@ -1,4 +1,8 @@
|
||||||
import { assertEquals, assertStringIncludes } from "./test_util.ts";
|
import {
|
||||||
|
assertEquals,
|
||||||
|
assertNotEquals,
|
||||||
|
assertStringIncludes,
|
||||||
|
} from "./test_util.ts";
|
||||||
|
|
||||||
Deno.test(function customInspectFunction() {
|
Deno.test(function customInspectFunction() {
|
||||||
const blob = new DOMException("test");
|
const blob = new DOMException("test");
|
||||||
|
@ -8,3 +12,13 @@ Deno.test(function customInspectFunction() {
|
||||||
);
|
);
|
||||||
assertStringIncludes(Deno.inspect(DOMException.prototype), "DOMException");
|
assertStringIncludes(Deno.inspect(DOMException.prototype), "DOMException");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Deno.test(function nameToCodeMappingPrototypeAccess() {
|
||||||
|
const newCode = 100;
|
||||||
|
const objectPrototype = Object.prototype as unknown as {
|
||||||
|
pollution: number;
|
||||||
|
};
|
||||||
|
objectPrototype.pollution = newCode;
|
||||||
|
assertNotEquals(newCode, new DOMException("test", "pollution").code);
|
||||||
|
Reflect.deleteProperty(objectPrototype, "pollution");
|
||||||
|
});
|
||||||
|
|
|
@ -15,16 +15,22 @@
|
||||||
Error,
|
Error,
|
||||||
ErrorPrototype,
|
ErrorPrototype,
|
||||||
ObjectDefineProperty,
|
ObjectDefineProperty,
|
||||||
|
ObjectCreate,
|
||||||
ObjectEntries,
|
ObjectEntries,
|
||||||
ObjectPrototypeIsPrototypeOf,
|
ObjectPrototypeIsPrototypeOf,
|
||||||
ObjectSetPrototypeOf,
|
ObjectSetPrototypeOf,
|
||||||
|
Symbol,
|
||||||
SymbolFor,
|
SymbolFor,
|
||||||
} = window.__bootstrap.primordials;
|
} = window.__bootstrap.primordials;
|
||||||
const webidl = window.__bootstrap.webidl;
|
const webidl = window.__bootstrap.webidl;
|
||||||
const consoleInternal = window.__bootstrap.console;
|
const consoleInternal = window.__bootstrap.console;
|
||||||
|
|
||||||
|
const _name = Symbol("name");
|
||||||
|
const _message = Symbol("message");
|
||||||
|
const _code = Symbol("code");
|
||||||
|
|
||||||
// Defined in WebIDL 4.3.
|
// Defined in WebIDL 4.3.
|
||||||
// https://heycam.github.io/webidl/#idl-DOMException
|
// https://webidl.spec.whatwg.org/#idl-DOMException
|
||||||
const INDEX_SIZE_ERR = 1;
|
const INDEX_SIZE_ERR = 1;
|
||||||
const DOMSTRING_SIZE_ERR = 2;
|
const DOMSTRING_SIZE_ERR = 2;
|
||||||
const HIERARCHY_REQUEST_ERR = 3;
|
const HIERARCHY_REQUEST_ERR = 3;
|
||||||
|
@ -52,52 +58,60 @@
|
||||||
const DATA_CLONE_ERR = 25;
|
const DATA_CLONE_ERR = 25;
|
||||||
|
|
||||||
// Defined in WebIDL 2.8.1.
|
// Defined in WebIDL 2.8.1.
|
||||||
// https://heycam.github.io/webidl/#dfn-error-names-table
|
// https://webidl.spec.whatwg.org/#dfn-error-names-table
|
||||||
/** @type {Record<string, number>} */
|
/** @type {Record<string, number>} */
|
||||||
const nameToCodeMapping = {
|
// the prototype should be null, to prevent user code from looking
|
||||||
IndexSizeError: INDEX_SIZE_ERR,
|
// up Object.prototype properties, such as "toString"
|
||||||
HierarchyRequestError: HIERARCHY_REQUEST_ERR,
|
const nameToCodeMapping = ObjectCreate(null, {
|
||||||
WrongDocumentError: WRONG_DOCUMENT_ERR,
|
IndexSizeError: { value: INDEX_SIZE_ERR },
|
||||||
InvalidCharacterError: INVALID_CHARACTER_ERR,
|
HierarchyRequestError: { value: HIERARCHY_REQUEST_ERR },
|
||||||
NoModificationAllowedError: NO_MODIFICATION_ALLOWED_ERR,
|
WrongDocumentError: { value: WRONG_DOCUMENT_ERR },
|
||||||
NotFoundError: NOT_FOUND_ERR,
|
InvalidCharacterError: { value: INVALID_CHARACTER_ERR },
|
||||||
NotSupportedError: NOT_SUPPORTED_ERR,
|
NoModificationAllowedError: { value: NO_MODIFICATION_ALLOWED_ERR },
|
||||||
InUseAttributeError: INUSE_ATTRIBUTE_ERR,
|
NotFoundError: { value: NOT_FOUND_ERR },
|
||||||
InvalidStateError: INVALID_STATE_ERR,
|
NotSupportedError: { value: NOT_SUPPORTED_ERR },
|
||||||
SyntaxError: SYNTAX_ERR,
|
InUseAttributeError: { value: INUSE_ATTRIBUTE_ERR },
|
||||||
InvalidModificationError: INVALID_MODIFICATION_ERR,
|
InvalidStateError: { value: INVALID_STATE_ERR },
|
||||||
NamespaceError: NAMESPACE_ERR,
|
SyntaxError: { value: SYNTAX_ERR },
|
||||||
InvalidAccessError: INVALID_ACCESS_ERR,
|
InvalidModificationError: { value: INVALID_MODIFICATION_ERR },
|
||||||
TypeMismatchError: TYPE_MISMATCH_ERR,
|
NamespaceError: { value: NAMESPACE_ERR },
|
||||||
SecurityError: SECURITY_ERR,
|
InvalidAccessError: { value: INVALID_ACCESS_ERR },
|
||||||
NetworkError: NETWORK_ERR,
|
TypeMismatchError: { value: TYPE_MISMATCH_ERR },
|
||||||
AbortError: ABORT_ERR,
|
SecurityError: { value: SECURITY_ERR },
|
||||||
URLMismatchError: URL_MISMATCH_ERR,
|
NetworkError: { value: NETWORK_ERR },
|
||||||
QuotaExceededError: QUOTA_EXCEEDED_ERR,
|
AbortError: { value: ABORT_ERR },
|
||||||
TimeoutError: TIMEOUT_ERR,
|
URLMismatchError: { value: URL_MISMATCH_ERR },
|
||||||
InvalidNodeTypeError: INVALID_NODE_TYPE_ERR,
|
QuotaExceededError: { value: QUOTA_EXCEEDED_ERR },
|
||||||
DataCloneError: DATA_CLONE_ERR,
|
TimeoutError: { value: TIMEOUT_ERR },
|
||||||
};
|
InvalidNodeTypeError: { value: INVALID_NODE_TYPE_ERR },
|
||||||
|
DataCloneError: { value: DATA_CLONE_ERR },
|
||||||
|
});
|
||||||
|
|
||||||
// Defined in WebIDL 4.3.
|
// Defined in WebIDL 4.3.
|
||||||
// https://heycam.github.io/webidl/#idl-DOMException
|
// https://webidl.spec.whatwg.org/#idl-DOMException
|
||||||
class DOMException {
|
class DOMException {
|
||||||
#message = "";
|
[_message];
|
||||||
#name = "";
|
[_name];
|
||||||
#code = 0;
|
[_code];
|
||||||
|
|
||||||
|
// https://webidl.spec.whatwg.org/#dom-domexception-domexception
|
||||||
constructor(message = "", name = "Error") {
|
constructor(message = "", name = "Error") {
|
||||||
this.#message = webidl.converters.DOMString(message, {
|
message = webidl.converters.DOMString(message, {
|
||||||
prefix: "Failed to construct 'DOMException'",
|
prefix: "Failed to construct 'DOMException'",
|
||||||
context: "Argument 1",
|
context: "Argument 1",
|
||||||
});
|
});
|
||||||
this.#name = webidl.converters.DOMString(name, {
|
name = webidl.converters.DOMString(name, {
|
||||||
prefix: "Failed to construct 'DOMException'",
|
prefix: "Failed to construct 'DOMException'",
|
||||||
context: "Argument 2",
|
context: "Argument 2",
|
||||||
});
|
});
|
||||||
this.#code = nameToCodeMapping[this.#name] ?? 0;
|
const code = nameToCodeMapping[name] ?? 0;
|
||||||
|
|
||||||
const error = new Error(this.#message);
|
this[_message] = message;
|
||||||
|
this[_name] = name;
|
||||||
|
this[_code] = code;
|
||||||
|
this[webidl.brand] = webidl.brand;
|
||||||
|
|
||||||
|
const error = new Error(message);
|
||||||
error.name = "DOMException";
|
error.name = "DOMException";
|
||||||
ObjectDefineProperty(this, "stack", {
|
ObjectDefineProperty(this, "stack", {
|
||||||
value: error.stack,
|
value: error.stack,
|
||||||
|
@ -115,20 +129,23 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
get message() {
|
get message() {
|
||||||
return this.#message;
|
webidl.assertBranded(this, DOMExceptionPrototype);
|
||||||
|
return this[_message];
|
||||||
}
|
}
|
||||||
|
|
||||||
get name() {
|
get name() {
|
||||||
return this.#name;
|
webidl.assertBranded(this, DOMExceptionPrototype);
|
||||||
|
return this[_name];
|
||||||
}
|
}
|
||||||
|
|
||||||
get code() {
|
get code() {
|
||||||
return this.#code;
|
webidl.assertBranded(this, DOMExceptionPrototype);
|
||||||
|
return this[_code];
|
||||||
}
|
}
|
||||||
|
|
||||||
[SymbolFor("Deno.customInspect")](inspect) {
|
[SymbolFor("Deno.customInspect")](inspect) {
|
||||||
if (ObjectPrototypeIsPrototypeOf(DOMExceptionPrototype, this)) {
|
if (ObjectPrototypeIsPrototypeOf(DOMExceptionPrototype, this)) {
|
||||||
return `DOMException: ${this.#message}`;
|
return `DOMException: ${this[_message]}`;
|
||||||
} else {
|
} else {
|
||||||
return inspect(consoleInternal.createFilteredInspectProxy({
|
return inspect(consoleInternal.createFilteredInspectProxy({
|
||||||
object: this,
|
object: this,
|
||||||
|
|
Loading…
Reference in a new issue