diff --git a/ext/web/01_dom_exception.js b/ext/web/01_dom_exception.js index 811f49987225fb..fb7bbdc707940b 100644 --- a/ext/web/01_dom_exception.js +++ b/ext/web/01_dom_exception.js @@ -81,7 +81,6 @@ const nameToCodeMapping = ObjectCreate(null, { 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 }, @@ -194,4 +193,42 @@ for (let i = 0; i < entries.length; ++i) { ObjectDefineProperty(DOMException.prototype, key, desc); } -export { DOMException, DOMExceptionPrototype }; +// Defined in WebIDL 4.3. +// https://webidl.spec.whatwg.org/#quotaexceedederror +class QuotaExceededError extends DOMException { + #quota = null; + #requested = null; + + constructor(message = "", options = { __proto__: null }) { + message = webidl.converters.DOMString( + message, + "Failed to construct 'QuotaExceededError'", + "Argument 1", + ); + super(message, "QuotaExceededError"); + + if (options !== null && options !== undefined) { + if (ObjectHasOwn(options, "quota")) { + this.#quota = options.quota ?? null; + } + if (ObjectHasOwn(options, "requested")) { + this.#requested = options.requested ?? null; + } + } + } + + get quota() { + webidl.assertBranded(this, QuotaExceededErrorPrototype); + return this.#quota; + } + + get requested() { + webidl.assertBranded(this, QuotaExceededErrorPrototype); + return this.#requested; + } +} + +webidl.configureInterface(QuotaExceededError); +const QuotaExceededErrorPrototype = QuotaExceededError.prototype; + +export { DOMException, DOMExceptionPrototype, QuotaExceededError }; diff --git a/runtime/js/99_main.js b/runtime/js/99_main.js index b77f96bd0bba4e..7af9c629d5360b 100644 --- a/runtime/js/99_main.js +++ b/runtime/js/99_main.js @@ -76,7 +76,7 @@ import { } from "ext:runtime/90_deno_ns.js"; import { errors } from "ext:runtime/01_errors.js"; import * as webidl from "ext:deno_webidl/00_webidl.js"; -import { DOMException } from "ext:deno_web/01_dom_exception.js"; +import { DOMException, QuotaExceededError } from "ext:deno_web/01_dom_exception.js"; import { unstableForWindowOrWorkerGlobalScope, windowOrWorkerGlobalScope, @@ -309,11 +309,10 @@ function formatException(error) { ) { return null; } else if (typeof error == "string") { - return `Uncaught ${ - inspectArgs([quoteString(error, getDefaultInspectOptions())], { - colors: !getStderrNoColor(), - }) - }`; + return `Uncaught ${inspectArgs([quoteString(error, getDefaultInspectOptions())], { + colors: !getStderrNoColor(), + }) + }`; } else { return `Uncaught ${inspectArgs([error], { colors: !getStderrNoColor() })}`; } @@ -350,7 +349,7 @@ core.registerErrorBuilder( core.registerErrorBuilder( "DOMExceptionQuotaExceededError", function DOMExceptionQuotaExceededError(msg) { - return new DOMException(msg, "QuotaExceededError"); + return new QuotaExceededError(msg); }, ); core.registerErrorBuilder( @@ -566,8 +565,8 @@ const finalDenoNs = { // Deno.test, Deno.bench, Deno.lint are noops here, but kept for compatibility; so // that they don't cause errors when used outside of `deno test`/`deno bench`/`deno lint` // contexts. - test: () => {}, - bench: () => {}, + test: () => { }, + bench: () => { }, lint: { runPlugin: () => { throw new Error( diff --git a/tests/unit/dom_exception_test.ts b/tests/unit/dom_exception_test.ts index 2e0c9f71e17db6..aab2274230501e 100644 --- a/tests/unit/dom_exception_test.ts +++ b/tests/unit/dom_exception_test.ts @@ -30,3 +30,39 @@ Deno.test(function hasStackAccessor() { assert(typeof desc.get === "function"); assert(typeof desc.set === "function"); }); + +Deno.test(function quotaExceededErrorIsSubclass() { + const error = new QuotaExceededError("test message"); + assert(error instanceof QuotaExceededError); + assert(error instanceof DOMException); + assert(error instanceof Error); +}); + +Deno.test(function quotaExceededErrorCodeIsZero() { + // QuotaExceededError is now a subclass, not a DOMException name + // So creating a DOMException with name "QuotaExceededError" should have code 0 + const error = new DOMException("test", "QuotaExceededError"); + assertEquals(error.code, 0); +}); + +Deno.test(function quotaExceededErrorHasCorrectName() { + const error = new QuotaExceededError("test message"); + assertEquals(error.name, "QuotaExceededError"); +}); + +Deno.test(function quotaExceededErrorHasQuotaAndRequestedProperties() { + const error = new QuotaExceededError("test message"); + assertEquals(error.quota, null); + assertEquals(error.requested, null); +}); + +Deno.test(function quotaExceededErrorWithOptions() { + const error = new QuotaExceededError("test message", { + quota: 1000, + requested: 1500, + }); + assertEquals(error.quota, 1000); + assertEquals(error.requested, 1500); + assertEquals(error.message, "test message"); + assertEquals(error.name, "QuotaExceededError"); +});