Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add DOMException #991

Merged
merged 18 commits into from
Dec 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
## Changelog
##### Unreleased
- Added `DOMException` polyfill, [the Web IDL spec](https://webidl.spec.whatwg.org/#idl-DOMException), [see MDN](https://developer.mozilla.org/en-US/docs/Web/API/DOMException)
- Includes `DOMException` and its attributes polyfills with fixes of many different engines bugs
- Includes `DOMException#stack` property polyfill in engines that should have it
- Reuses native `DOMException` implementations where it's possible (for example, in old NodeJS where it's not exposed as global)
- Added [support of `cause` on all Error types](https://github.com/tc39/proposal-error-cause)
- Added `Error.prototype.toString` polyfill with many different engines bugs fixes
- Added `Number.prototype.toExponential` method polyfill with many different fixes for the most engines
- [`Array` grouping proposal](https://github.com/tc39/proposal-array-grouping):
- Moved to the stage 2
Expand Down
45 changes: 42 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ Promise.resolve(32).then(x => console.log(x)); // => 32
- [`setImmediate`](#setimmediate)
- [`queueMicrotask`](#queuemicrotask)
- [`URL` and `URLSearchParams`](#url-and-urlsearchparams)
- [`DOMException`](#domexception)
- [iterable DOM collections](#iterable-dom-collections)
- [Iteration helpers](#iteration-helpers)
- [Missing polyfills](#missing-polyfills)
Expand Down Expand Up @@ -538,8 +539,8 @@ class Function {
core-js/es|stable|features/function
core-js/es|stable|features/function/name
core-js/es|stable|features/function/has-instance
core-js/es|stable|features/function/bind
core-js/es|stable|features/function/virtual/bind
core-js(-pure)/es|stable|features/function/bind
core-js(-pure)/es|stable|features/function/virtual/bind
```
[*Example*](http://goo.gl/zqu3Wp):
```js
Expand Down Expand Up @@ -571,14 +572,19 @@ class AggregateError {
errors: Array<any>;
message: string;
}

class Error {
toString(): string; // different fixes
}
```
[*CommonJS entry points:*](#commonjs-api)
```
core-js(-pure)/es|stable|features/aggregate-error
core-js/es|stable|features/error
core-js/es|stable|features/error/constructor
core-js/es|stable|features/error/to-string
```
[*Example*](is.gd/79jmO5):
[*Example*](https://is.gd/1SufcH):
```js
const error1 = new TypeError('Error 1');
const error2 = new TypeError('Error 2');
Expand All @@ -589,6 +595,8 @@ aggregate.errors[1] === error2; // => true
const cause = new TypeError('Something wrong');
const error = new TypeError('Here explained what`s wrong', { cause });
error.cause === cause; // => true

Error.prototype.toString.call({ message: 1, name: 2 }) === '2: 1'; // => true
```

#### ECMAScript: Array[⬆](#index)
Expand Down Expand Up @@ -3008,6 +3016,37 @@ console.log(params.toString()); // => 'a=1&a=3&a=2&b=2&c=4'
- Legacy encodings in a search query are not supported. Also, `core-js` implementation has some other encoding-related issues.
- `URL` implementations from all of the popular browsers have much more problems than `core-js`, however, replacing all of them does not looks like a good idea. You can customize the aggressiveness of polyfill [by your requirements](#configurable-level-of-aggressiveness).

##### `DOMException`:[⬆](#index)
[The specification.](https://webidl.spec.whatwg.org/#idl-DOMException) Modules [`web.dom-exception.constructor`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.dom-exception.constructor.js), [`web.dom-exception.stack`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.dom-exception.stack.js), [`web.dom-exception.to-string-tag`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.dom-exception.to-string-tag.js).
```js
class DOMException {
constructor(message: string, name?: string);
readonly attribute name: string;
readonly attribute message: string;
readonly attribute code: string;
attribute stack: string; // in engines that should have it
@@toStringTag: 'DOMException';
}
````
[*CommonJS entry points:*](#commonjs-api)
```js
core-js(-pure)/stable|features/dom-exception
core-js(-pure)/stable|features/dom-exception/constructor
core-js/stable|features/dom-exception/to-string-tag
```
[*Examples*](is.gd/pI6oTN):
```js
const exception = new DOMException('error', 'DataCloneError');
console.log(exception.name); // => 'DataCloneError'
console.log(exception.message); // => 'error'
console.log(exception.code); // => 25
console.log(typeof exception.stack); // => 'string'
console.log(exception instanceof DOMException); // => true
console.log(exception instanceof Error); // => true
console.log(exception.toString()); // => 'DataCloneError: error'
console.log(Object.prototype.toString.call(exception)); // => '[object DOMException]'
```

#### Iterable DOM collections[⬆](#index)
Some DOM collections should have [iterable interface](https://heycam.github.io/webidl/#idl-iterable) or should be [inherited from `Array`](https://heycam.github.io/webidl/#LegacyArrayClass). That means they should have `forEach`, `keys`, `values`, `entries` and `@@iterator` methods for iteration. So add them. Modules [`web.dom-collections.iterator`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.dom-collections.iterator.js) and [`web.dom-collections.for-each`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.dom-collections.for-each.js).
```js
Expand Down
25 changes: 25 additions & 0 deletions packages/core-js-compat/src/data.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@ export const data = {
firefox: '91',
safari: '15.0',
},
'es.error.to-string': {
chrome: '33',
firefox: '11',
ie: '9',
safari: '8.0',
},
'es.aggregate-error': {
chrome: '85',
firefox: '79',
Expand Down Expand Up @@ -1813,6 +1819,25 @@ export const data = {
safari: '13.1',
rhino: '1.7.13',
},
'web.dom-exception.constructor': {
chrome: '46',
deno: '1.7',
firefox: '37',
node: '17.0',
safari: '11.1',
},
'web.dom-exception.stack': {
deno: '1.7',
firefox: '37',
node: '17.0',
},
'web.dom-exception.to-string-tag': {
chrome: '49',
deno: '1.7',
firefox: '51',
node: '17.0',
safari: '11.1',
},
'web.immediate': {
ie: '10',
node: '0.9.1',
Expand Down
4 changes: 4 additions & 0 deletions packages/core-js-compat/src/modules-by-versions.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ export default {
],
'3.20': [
'es.error.cause',
'es.error.to-string',
'es.aggregate-error.cause',
'es.number.to-exponential',
'esnext.array.group-by-map',
Expand All @@ -129,5 +130,8 @@ export default {
'esnext.typed-array.to-sorted',
'esnext.typed-array.to-spliced',
'esnext.typed-array.with',
'web.dom-exception.constructor',
'web.dom-exception.stack',
'web.dom-exception.to-string-tag',
],
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// empty
1 change: 1 addition & 0 deletions packages/core-js/es/error/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require('../../modules/es.error.cause');
require('../../modules/es.error.to-string');
var path = require('../../internals/path');

module.exports = path;
4 changes: 4 additions & 0 deletions packages/core-js/es/error/to-string.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
require('../../modules/es.error.to-string');
var toString = require('../../internals/error-to-string');

module.exports = toString;
3 changes: 3 additions & 0 deletions packages/core-js/features/dom-exception/constructor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
var parent = require('../../stable/dom-exception/constructor');

module.exports = parent;
3 changes: 3 additions & 0 deletions packages/core-js/features/dom-exception/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
var parent = require('../../stable/dom-exception');

module.exports = parent;
3 changes: 3 additions & 0 deletions packages/core-js/features/dom-exception/to-string-tag.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
var parent = require('../../stable/dom-exception/to-string-tag');

module.exports = parent;
3 changes: 3 additions & 0 deletions packages/core-js/features/error/to-string.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
var parent = require('../../stable/error/to-string');

module.exports = parent;
27 changes: 27 additions & 0 deletions packages/core-js/internals/dom-exception-constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
module.exports = {
IndexSizeError: { s: 'INDEX_SIZE_ERR', c: 1, m: 1 },
DOMStringSizeError: { s: 'DOMSTRING_SIZE_ERR', c: 2, m: 0 },
HierarchyRequestError: { s: 'HIERARCHY_REQUEST_ERR', c: 3, m: 1 },
WrongDocumentError: { s: 'WRONG_DOCUMENT_ERR', c: 4, m: 1 },
InvalidCharacterError: { s: 'INVALID_CHARACTER_ERR', c: 5, m: 1 },
NoDataAllowedError: { s: 'NO_DATA_ALLOWED_ERR', c: 6, m: 0 },
NoModificationAllowedError: { s: 'NO_MODIFICATION_ALLOWED_ERR', c: 7, m: 1 },
NotFoundError: { s: 'NOT_FOUND_ERR', c: 8, m: 1 },
NotSupportedError: { s: 'NOT_SUPPORTED_ERR', c: 9, m: 1 },
InUseAttributeError: { s: 'INUSE_ATTRIBUTE_ERR', c: 10, m: 1 },
InvalidStateError: { s: 'INVALID_STATE_ERR', c: 11, m: 1 },
SyntaxError: { s: 'SYNTAX_ERR', c: 12, m: 1 },
InvalidModificationError: { s: 'INVALID_MODIFICATION_ERR', c: 13, m: 1 },
NamespaceError: { s: 'NAMESPACE_ERR', c: 14, m: 1 },
InvalidAccessError: { s: 'INVALID_ACCESS_ERR', c: 15, m: 1 },
ValidationError: { s: 'VALIDATION_ERR', c: 16, m: 0 },
TypeMismatchError: { s: 'TYPE_MISMATCH_ERR', c: 17, m: 1 },
SecurityError: { s: 'SECURITY_ERR', c: 18, m: 1 },
NetworkError: { s: 'NETWORK_ERR', c: 19, m: 1 },
AbortError: { s: 'ABORT_ERR', c: 20, m: 1 },
URLMismatchError: { s: 'URL_MISMATCH_ERR', c: 21, m: 1 },
QuotaExceededError: { s: 'QUOTA_EXCEEDED_ERR', c: 22, m: 1 },
TimeoutError: { s: 'TIMEOUT_ERR', c: 23, m: 1 },
InvalidNodeTypeError: { s: 'INVALID_NODE_TYPE_ERR', c: 24, m: 1 },
DataCloneError: { s: 'DATA_CLONE_ERR', c: 25, m: 1 }
};
30 changes: 30 additions & 0 deletions packages/core-js/internals/error-to-string.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
'use strict';
var DESCRIPTORS = require('../internals/descriptors');
var fails = require('../internals/fails');
var anObject = require('../internals/an-object');
var create = require('../internals/object-create');
var normalizeStringArgument = require('../internals/normalize-string-argument');

var nativeErrorToString = Error.prototype.toString;

var INCORRECT_TO_STRING = fails(function () {
if (DESCRIPTORS) {
// Chrome 32- incorrectly call accessor
// eslint-disable-next-line es/no-object-defineproperty -- safe
var object = create(Object.defineProperty({}, 'name', { get: function () {
return this === object;
} }));
if (nativeErrorToString.call(object) !== 'true') return true;
}
// FF10- does not properly handle non-strings
return nativeErrorToString.call({ message: 1, name: 2 }) !== '2: 1'
// IE8 does not properly handle defaults
|| nativeErrorToString.call({}) !== 'Error';
});

module.exports = INCORRECT_TO_STRING ? function toString() {
var O = anObject(this);
var name = normalizeStringArgument(O.name, 'Error');
var message = normalizeStringArgument(O.message);
return !name ? message : !message ? name : name + ': ' + message;
} : nativeErrorToString;
7 changes: 4 additions & 3 deletions packages/core-js/internals/set-to-string-tag.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ var wellKnownSymbol = require('../internals/well-known-symbol');

var TO_STRING_TAG = wellKnownSymbol('toStringTag');

module.exports = function (it, TAG, STATIC) {
if (it && !hasOwn(it = STATIC ? it : it.prototype, TO_STRING_TAG)) {
defineProperty(it, TO_STRING_TAG, { configurable: true, value: TAG });
module.exports = function (target, TAG, STATIC) {
if (target && !STATIC) target = target.prototype;
if (target && !hasOwn(target, TO_STRING_TAG)) {
defineProperty(target, TO_STRING_TAG, { configurable: true, value: TAG });
}
};
8 changes: 8 additions & 0 deletions packages/core-js/internals/try-node-require.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
var IS_NODE = require('../internals/engine-is-node');

module.exports = function (name) {
try {
// eslint-disable-next-line no-new-func -- safe
if (IS_NODE) return Function('return require("' + name + '")')();
} catch (error) { /* empty */ }
};
10 changes: 10 additions & 0 deletions packages/core-js/modules/es.error.to-string.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
var redefine = require('../internals/redefine');
var errorToString = require('../internals/error-to-string');

var ErrorPrototype = Error.prototype;

// `Error.prototype.toString` method fix
// https://tc39.es/ecma262/#sec-error.prototype.tostring
if (ErrorPrototype.toString !== errorToString) {
redefine(ErrorPrototype, 'toString', errorToString);
}