Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit b328bf7

Browse filesBrowse files
committed
lib,src: implement QuotaExceededError as DOMException-derived interface
Implement QuotaExceededError as a DOMException-derived interface per the WebIDL specification update. QuotaExceededError is now a proper constructor exposed as a global [Exposed=*] interface that extends DOMException with optional `quota` and `requested` attributes (both nullable doubles, defaulting to null). The constructor validates that quota and requested are finite, non-negative, and that requested is not less than quota when both are provided. QuotaExceededError is [Serializable] and supports structuredClone, preserving the quota and requested values across the serialization boundary. Callers updated: - crypto.getRandomValues() now throws a QuotaExceededError instance - WebStorage (C++) now constructs QuotaExceededError directly Refs: https://redirect.github.com/whatwg/webidl/pull/1465 Fixes: #58987 PR-URL: #62293 Reviewed-By: Mattias Buelens <mattias@buelens.com> Reviewed-By: Chengzhong Wu <legendecas@gmail.com> Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
1 parent 4ee467f commit b328bf7
Copy full SHA for b328bf7

15 files changed

+376-75Lines changed: 376 additions & 75 deletions
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎doc/api/globals.md‎

Copy file name to clipboardExpand all lines: doc/api/globals.md
+8Lines changed: 8 additions & 0 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -976,6 +976,14 @@ DataHandler.prototype.load = async function load(key) {
976976
};
977977
```
978978

979+
## Class: `QuotaExceededError`
980+
981+
<!-- YAML
982+
added: REPLACEME
983+
-->
984+
985+
The WHATWG {QuotaExceededError} class. Extends {DOMException}.
986+
979987
## Class: `ReadableByteStreamController`
980988

981989
<!-- YAML
Collapse file

‎eslint.config.mjs‎

Copy file name to clipboardExpand all lines: eslint.config.mjs
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ export default [
130130
Float16Array: 'readonly',
131131
FormData: 'readonly',
132132
navigator: 'readonly',
133+
QuotaExceededError: 'readonly',
133134
ReadableStream: 'readonly',
134135
ReadableStreamDefaultReader: 'readonly',
135136
ReadableStreamBYOBReader: 'readonly',
Collapse file

‎lib/eslint.config_partial.mjs‎

Copy file name to clipboardExpand all lines: lib/eslint.config_partial.mjs
+5-1Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ const noRestrictedSyntax = [
2323
message: "`btoa` supports only latin-1 charset, use Buffer.from(str).toString('base64') instead",
2424
},
2525
{
26-
selector: 'NewExpression[callee.name=/Error$/]:not([callee.name=/^(AssertionError|NghttpError|AbortError|NodeAggregateError)$/])',
26+
selector: 'NewExpression[callee.name=/Error$/]:not([callee.name=/^(AssertionError|NghttpError|AbortError|NodeAggregateError|QuotaExceededError)$/])',
2727
message: "Use an error exported by 'internal/errors' instead.",
2828
},
2929
{
@@ -122,6 +122,10 @@ export default [
122122
name: 'DOMException',
123123
message: "Use lazy function `const { lazyDOMExceptionClass } = require('internal/util');` instead of the global.",
124124
},
125+
{
126+
name: 'QuotaExceededError',
127+
message: "Use `internalBinding('messaging').QuotaExceededError` instead of the global.",
128+
},
125129
{
126130
name: 'ErrorEvent',
127131
message: "Use `const { ErrorEvent } = require('internal/deps/undici/undici');` instead of the global.",
Collapse file

‎lib/internal/bootstrap/web/exposed-wildcard.js‎

Copy file name to clipboardExpand all lines: lib/internal/bootstrap/web/exposed-wildcard.js
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ exposeInterface(globalThis, 'URL', URL);
2929
exposeInterface(globalThis, 'URLSearchParams', URLSearchParams);
3030
exposeLazyDOMExceptionProperty(globalThis);
3131

32+
// https://webidl.spec.whatwg.org/#quotaexceedederror
33+
exposeLazyInterfaces(globalThis, 'internal/worker/clone_dom_exception', [
34+
'QuotaExceededError',
35+
]);
36+
3237
// https://dom.spec.whatwg.org/#interface-abortcontroller
3338
// Lazy ones.
3439
exposeLazyInterfaces(globalThis, 'internal/abort_controller', [
Collapse file

‎lib/internal/crypto/random.js‎

Copy file name to clipboardExpand all lines: lib/internal/crypto/random.js
+3-3Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -328,9 +328,9 @@ function getRandomValues(data) {
328328
'TypeMismatchError');
329329
}
330330
if (data.byteLength > 65536) {
331-
throw lazyDOMException(
332-
'The requested length exceeds 65,536 bytes',
333-
'QuotaExceededError');
331+
const { QuotaExceededError } = internalBinding('messaging');
332+
throw new QuotaExceededError(
333+
'The requested length exceeds 65,536 bytes');
334334
}
335335
randomFillSync(data, 0);
336336
return data;
Collapse file

‎lib/internal/per_context/domexception.js‎

Copy file name to clipboardExpand all lines: lib/internal/per_context/domexception.js
+91Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@
33
const {
44
Error,
55
ErrorPrototype,
6+
NumberIsFinite,
7+
NumberIsNaN,
68
ObjectDefineProperties,
79
ObjectDefineProperty,
810
ObjectSetPrototypeOf,
11+
RangeError,
912
SafeMap,
1013
SafeSet,
1114
SafeWeakMap,
@@ -203,3 +206,91 @@ for (const { 0: name, 1: codeName, 2: value } of [
203206
}
204207

205208
exports.DOMException = DOMException;
209+
210+
// https://webidl.spec.whatwg.org/#quotaexceedederror
211+
class QuotaExceededError extends DOMException {
212+
#quota;
213+
#requested;
214+
215+
constructor(message = '', options = { __proto__: null }) {
216+
super(message, 'QuotaExceededError');
217+
this[transfer_mode_private_symbol] = kCloneable;
218+
219+
let quota = null;
220+
let requested = null;
221+
222+
if (options !== null && options !== undefined) {
223+
if ('quota' in options) {
224+
quota = +options.quota;
225+
if (!NumberIsFinite(quota)) {
226+
// eslint-disable-next-line no-restricted-syntax
227+
throw new TypeError(
228+
`Cannot convert options.quota to a double: the value is ${NumberIsNaN(quota) ? 'NaN' : 'Infinity'}`,
229+
);
230+
}
231+
if (quota < 0) {
232+
// eslint-disable-next-line no-restricted-syntax
233+
throw new RangeError('options.quota must not be negative');
234+
}
235+
}
236+
237+
if ('requested' in options) {
238+
requested = +options.requested;
239+
if (!NumberIsFinite(requested)) {
240+
// eslint-disable-next-line no-restricted-syntax
241+
throw new TypeError(
242+
`Cannot convert options.requested to a double: the value is ${NumberIsNaN(requested) ? 'NaN' : 'Infinity'}`,
243+
);
244+
}
245+
if (requested < 0) {
246+
// eslint-disable-next-line no-restricted-syntax
247+
throw new RangeError('options.requested must not be negative');
248+
}
249+
}
250+
}
251+
252+
if (quota !== null && requested !== null && requested < quota) {
253+
// eslint-disable-next-line no-restricted-syntax
254+
throw new RangeError('options.requested must not be less than options.quota');
255+
}
256+
257+
this.#quota = quota;
258+
this.#requested = requested;
259+
}
260+
261+
[messaging_clone_symbol]() {
262+
const domExceptionClone = DOMExceptionPrototype[messaging_clone_symbol].call(this);
263+
domExceptionClone.data.quota = this.#quota;
264+
domExceptionClone.data.requested = this.#requested;
265+
domExceptionClone.deserializeInfo = 'internal/worker/clone_dom_exception:QuotaExceededError';
266+
return domExceptionClone;
267+
}
268+
269+
[messaging_deserialize_symbol](data) {
270+
DOMExceptionPrototype[messaging_deserialize_symbol].call(this, data);
271+
this.#quota = data.quota;
272+
this.#requested = data.requested;
273+
}
274+
275+
get quota() {
276+
if (!(#quota in this)) {
277+
throwInvalidThisError(TypeError, 'QuotaExceededError');
278+
}
279+
return this.#quota;
280+
}
281+
282+
get requested() {
283+
if (!(#requested in this)) {
284+
throwInvalidThisError(TypeError, 'QuotaExceededError');
285+
}
286+
return this.#requested;
287+
}
288+
}
289+
290+
ObjectDefineProperties(QuotaExceededError.prototype, {
291+
[SymbolToStringTag]: { __proto__: null, configurable: true, value: 'QuotaExceededError' },
292+
quota: { __proto__: null, enumerable: true, configurable: true },
293+
requested: { __proto__: null, enumerable: true, configurable: true },
294+
});
295+
296+
exports.QuotaExceededError = QuotaExceededError;
Collapse file
+4-2Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
'use strict';
22

3-
// Delegate to the actual DOMException implementation.
3+
// Delegate to the actual DOMException/QuotaExceededError implementation.
4+
const messaging = internalBinding('messaging');
45
module.exports = {
5-
DOMException: internalBinding('messaging').DOMException,
6+
DOMException: messaging.DOMException,
7+
QuotaExceededError: messaging.QuotaExceededError,
68
};
Collapse file

‎src/node_messaging.cc‎

Copy file name to clipboardExpand all lines: src/node_messaging.cc
+15Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1762,6 +1762,21 @@ static void CreatePerContextProperties(Local<Object> target,
17621762
domexception)
17631763
.Check();
17641764
}
1765+
{
1766+
Local<Object> per_context_bindings;
1767+
Local<Value> quota_exceeded_error_val;
1768+
if (GetPerContextExports(context).ToLocal(&per_context_bindings) &&
1769+
per_context_bindings
1770+
->Get(context,
1771+
FIXED_ONE_BYTE_STRING(env->isolate(), "QuotaExceededError"))
1772+
.ToLocal(&quota_exceeded_error_val)) {
1773+
target
1774+
->Set(context,
1775+
FIXED_ONE_BYTE_STRING(env->isolate(), "QuotaExceededError"),
1776+
quota_exceeded_error_val)
1777+
.Check();
1778+
}
1779+
}
17651780
}
17661781

17671782
static void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
Collapse file

‎src/node_webstorage.cc‎

Copy file name to clipboardExpand all lines: src/node_webstorage.cc
+9-9Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,23 +57,23 @@ using v8::Value;
5757

5858
static void ThrowQuotaExceededException(Local<Context> context) {
5959
Isolate* isolate = Isolate::GetCurrent();
60-
auto dom_exception_str = FIXED_ONE_BYTE_STRING(isolate, "DOMException");
61-
auto err_name = FIXED_ONE_BYTE_STRING(isolate, "QuotaExceededError");
60+
auto quota_exceeded_str =
61+
FIXED_ONE_BYTE_STRING(isolate, "QuotaExceededError");
6262
auto err_message =
6363
FIXED_ONE_BYTE_STRING(isolate, "Setting the value exceeded the quota");
6464
Local<Object> per_context_bindings;
65-
Local<Value> domexception_ctor_val;
65+
Local<Value> quota_exceeded_ctor_val;
6666
if (!GetPerContextExports(context).ToLocal(&per_context_bindings) ||
67-
!per_context_bindings->Get(context, dom_exception_str)
68-
.ToLocal(&domexception_ctor_val)) {
67+
!per_context_bindings->Get(context, quota_exceeded_str)
68+
.ToLocal(&quota_exceeded_ctor_val)) {
6969
return;
7070
}
71-
CHECK(domexception_ctor_val->IsFunction());
72-
Local<Function> domexception_ctor = domexception_ctor_val.As<Function>();
73-
Local<Value> argv[] = {err_message, err_name};
71+
CHECK(quota_exceeded_ctor_val->IsFunction());
72+
Local<Function> quota_exceeded_ctor = quota_exceeded_ctor_val.As<Function>();
73+
Local<Value> argv[] = {err_message};
7474
Local<Value> exception;
7575

76-
if (!domexception_ctor->NewInstance(context, arraysize(argv), argv)
76+
if (!quota_exceeded_ctor->NewInstance(context, arraysize(argv), argv)
7777
.ToLocal(&exception)) {
7878
return;
7979
}
Collapse file

‎test/common/globals.js‎

Copy file name to clipboardExpand all lines: test/common/globals.js
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ intrinsics.add('console');
7979

8080
const webIdlExposedWildcard = new Set([
8181
'DOMException',
82+
'QuotaExceededError',
8283
'TextEncoder',
8384
'TextDecoder',
8485
'AbortController',

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.