GeezerVison is showing github.com — lib,src: implement QuotaExceededError as DOMException-derived interface · nodejs/node@b328bf7
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file 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 number | Diff line number | Diff line change |
|---|
@@ -976,6 +976,14 @@ DataHandler.prototype.load = async function load(key) { | 976 | 976 | }; | 977 | 977 | ``` | 978 | 978 |
| | 979 | +## Class: `QuotaExceededError` | | 980 | + | | 981 | +<!-- YAML | | 982 | +added: REPLACEME | | 983 | +--> | | 984 | + | | 985 | +The WHATWG {QuotaExceededError} class. Extends {DOMException}. | | 986 | + | 979 | 987 | ## Class: `ReadableByteStreamController` | 980 | 988 |
| 981 | 989 | <!-- YAML | |
Collapse file Copy file name to clipboardExpand all lines: eslint.config.mjs +1Lines changed: 1 addition & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -130,6 +130,7 @@ export default [ | 130 | 130 | Float16Array: 'readonly', | 131 | 131 | FormData: 'readonly', | 132 | 132 | navigator: 'readonly', | | 133 | + QuotaExceededError: 'readonly', | 133 | 134 | ReadableStream: 'readonly', | 134 | 135 | ReadableStreamDefaultReader: 'readonly', | 135 | 136 | ReadableStreamBYOBReader: 'readonly', | |
Collapse file Copy file name to clipboardExpand all lines: lib/eslint.config_partial.mjs +5-1Lines changed: 5 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -23,7 +23,7 @@ const noRestrictedSyntax = [ | 23 | 23 | message: "`btoa` supports only latin-1 charset, use Buffer.from(str).toString('base64') instead", | 24 | 24 | }, | 25 | 25 | { | 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)$/])', | 27 | 27 | message: "Use an error exported by 'internal/errors' instead.", | 28 | 28 | }, | 29 | 29 | { | @@ -122,6 +122,10 @@ export default [ | 122 | 122 | name: 'DOMException', | 123 | 123 | message: "Use lazy function `const { lazyDOMExceptionClass } = require('internal/util');` instead of the global.", | 124 | 124 | }, | | 125 | + { | | 126 | + name: 'QuotaExceededError', | | 127 | + message: "Use `internalBinding('messaging').QuotaExceededError` instead of the global.", | | 128 | + }, | 125 | 129 | { | 126 | 130 | name: 'ErrorEvent', | 127 | 131 | message: "Use `const { ErrorEvent } = require('internal/deps/undici/undici');` instead of the global.", | |
Collapse file Copy file name to clipboardExpand all lines: lib/internal/bootstrap/web/exposed-wildcard.js +5Lines changed: 5 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -29,6 +29,11 @@ exposeInterface(globalThis, 'URL', URL); | 29 | 29 | exposeInterface(globalThis, 'URLSearchParams', URLSearchParams); | 30 | 30 | exposeLazyDOMExceptionProperty(globalThis); | 31 | 31 |
| | 32 | +// https://webidl.spec.whatwg.org/#quotaexceedederror | | 33 | +exposeLazyInterfaces(globalThis, 'internal/worker/clone_dom_exception', [ | | 34 | + 'QuotaExceededError', | | 35 | +]); | | 36 | + | 32 | 37 | // https://dom.spec.whatwg.org/#interface-abortcontroller | 33 | 38 | // Lazy ones. | 34 | 39 | exposeLazyInterfaces(globalThis, 'internal/abort_controller', [ | |
Collapse file Copy file name to clipboardExpand all lines: lib/internal/crypto/random.js +3-3Lines changed: 3 additions & 3 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -328,9 +328,9 @@ function getRandomValues(data) { | 328 | 328 | 'TypeMismatchError'); | 329 | 329 | } | 330 | 330 | 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'); | 334 | 334 | } | 335 | 335 | randomFillSync(data, 0); | 336 | 336 | return data; | |
Collapse file Copy file name to clipboardExpand all lines: lib/internal/per_context/domexception.js +91Lines changed: 91 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 3 | 3 | const { | 4 | 4 | Error, | 5 | 5 | ErrorPrototype, | | 6 | + NumberIsFinite, | | 7 | + NumberIsNaN, | 6 | 8 | ObjectDefineProperties, | 7 | 9 | ObjectDefineProperty, | 8 | 10 | ObjectSetPrototypeOf, | | 11 | + RangeError, | 9 | 12 | SafeMap, | 10 | 13 | SafeSet, | 11 | 14 | SafeWeakMap, | @@ -203,3 +206,91 @@ for (const { 0: name, 1: codeName, 2: value } of [ | 203 | 206 | } | 204 | 207 |
| 205 | 208 | 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 Copy file name to clipboard +4-2Lines changed: 4 additions & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 1 | 1 | 'use strict'; | 2 | 2 |
| 3 | | -// Delegate to the actual DOMException implementation. | | 3 | +// Delegate to the actual DOMException/QuotaExceededError implementation. | | 4 | +const messaging = internalBinding('messaging'); | 4 | 5 | module.exports = { | 5 | | - DOMException: internalBinding('messaging').DOMException, | | 6 | + DOMException: messaging.DOMException, | | 7 | + QuotaExceededError: messaging.QuotaExceededError, | 6 | 8 | }; |
Collapse file Copy file name to clipboardExpand all lines: src/node_messaging.cc +15Lines changed: 15 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -1762,6 +1762,21 @@ static void CreatePerContextProperties(Local<Object> target, | 1762 | 1762 | domexception) | 1763 | 1763 | .Check(); | 1764 | 1764 | } | | 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("a_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 | + } | 1765 | 1780 | } | 1766 | 1781 |
| 1767 | 1782 | static void RegisterExternalReferences(ExternalReferenceRegistry* registry) { | |
Collapse file Copy file name to clipboardExpand all lines: src/node_webstorage.cc +9-9Lines changed: 9 additions & 9 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -57,23 +57,23 @@ using v8::Value; | 57 | 57 |
| 58 | 58 | static void ThrowQuotaExceededException(Local<Context> context) { | 59 | 59 | 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"); | 62 | 62 | auto err_message = | 63 | 63 | FIXED_ONE_BYTE_STRING(isolate, "Setting the value exceeded the quota"); | 64 | 64 | Local<Object> per_context_bindings; | 65 | | - Local<Value> domexception_ctor_val; | | 65 | + Local<Value> quota_exceeded_ctor_val; | 66 | 66 | 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("a_exceeded_ctor_val)) { | 69 | 69 | return; | 70 | 70 | } | 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}; | 74 | 74 | Local<Value> exception; | 75 | 75 |
| 76 | | - if (!domexception_ctor->NewInstance(context, arraysize(argv), argv) | | 76 | + if (!quota_exceeded_ctor->NewInstance(context, arraysize(argv), argv) | 77 | 77 | .ToLocal(&exception)) { | 78 | 78 | return; | 79 | 79 | } | |
Collapse file Copy file name to clipboardExpand all lines: test/common/globals.js +1Lines changed: 1 addition & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -79,6 +79,7 @@ intrinsics.add('console'); | 79 | 79 |
| 80 | 80 | const webIdlExposedWildcard = new Set([ | 81 | 81 | 'DOMException', | | 82 | + 'QuotaExceededError', | 82 | 83 | 'TextEncoder', | 83 | 84 | 'TextDecoder', | 84 | 85 | 'AbortController', | |
|