move Error.isError to stable ES

This commit is contained in:
Denis Pushkarev
2025-05-28 21:45:01 +03:00
parent 67c2dd6748
commit 44b911fb6c
16 changed files with 112 additions and 84 deletions
+5
View File
@@ -1,5 +1,10 @@
## Changelog
##### Unreleased
- [`Error.isError` proposal](https://github.com/tc39/proposal-is-error):
- Built-ins:
- `Error.isError`
- Moved to stable ES, May 2025 TC39 meeting
- Added `es.` namespace module, `/es/` and `/stable/` namespaces entries
- Always check regular expression flags by `flags` getter [PR](https://github.com/tc39/ecma262/pull/2791). Native methods are not fixed, only own implementation updated for:
- `RegExp.prototype[@@match]`
- `RegExp.prototype[@@replace]`
+32 -28
View File
@@ -137,6 +137,7 @@ structuredClone(new Set([1, 2, 3])); // => new Set([1, 2, 3])
- [Change `Array` by copy](#change-array-by-copy)
- [`Array` grouping](#array-grouping)
- [`ArrayBuffer.prototype.transfer` and friends](#arraybufferprototypetransfer-and-friends)
- [`Error.isError`](#erroriserror)
- [`Float16` methods](#float16-methods)
- [`Iterator` helpers](#iterator-helpers)
- [`Object.values` / `Object.entries`](#objectvalues--objectentries)
@@ -167,7 +168,6 @@ structuredClone(new Set([1, 2, 3])); // => new Set([1, 2, 3])
- [Explicit resource management](#explicit-resource-management)
- [`Math.sumPrecise`](#mathsumprecise)
- [`Symbol.metadata` for decorators metadata proposal](#symbolmetadata-for-decorators-metadata-proposal)
- [`Error.isError`](#erroriserror)
- [Stage 2.7 proposals](#stage-27-proposals)
- [`Iterator` sequencing](#iterator-sequencing)
- [`Map` upsert](#map-upsert)
@@ -627,7 +627,7 @@ console.log.bind(console, 42)(43); // => 42 43
```
#### ECMAScript: Error[⬆](#index)
Modules [`es.aggregate-error`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.aggregate-error.js), [`es.aggregate-error.cause`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.aggregate-error.cause.js), [`es.error.cause`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.error.cause.js), [`es.error.to-string`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.error.to-string.js).
Modules [`es.aggregate-error`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.aggregate-error.js), [`es.aggregate-error.cause`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.aggregate-error.cause.js), [`es.error.cause`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.error.cause.js), [`es.error.is-error`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.error.is-error.js), [`es.error.to-string`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.error.to-string.js).
```ts
class [
Error,
@@ -652,6 +652,7 @@ class AggregateError extends Error {
}
class Error {
static isError(value: any): boolean;
toString(): string; // different fixes
}
```
@@ -660,6 +661,7 @@ class Error {
core-js(-pure)/es|stable|actual|full/aggregate-error
core-js/es|stable|actual|full/error
core-js/es|stable|actual|full/error/constructor
core-js(-pure)/es|stable|actual|full/error/is-error
core-js/es|stable|actual|full/error/to-string
```
[*Example*](https://is.gd/1SufcH):
@@ -677,6 +679,20 @@ error.cause === cause; // => true
Error.prototype.toString.call({ message: 1, name: 2 }) === '2: 1'; // => true
```
[*Example*](https://tinyurl.com/23nauwoz):
```js
Error.isError(new Error('error')); // => true
Error.isError(new TypeError('error')); // => true
Error.isError(new DOMException('error')); // => true
Error.isError(null); // => false
Error.isError({}); // => false
Error.isError(Object.create(Error.prototype)); // => false
```
> [!WARNING]
> We have no bulletproof way to polyfill this `Error.isError` / check if the object is an error, so it's an enough naive implementation.
#### ECMAScript: Array[⬆](#index)
Modules [`es.array.from`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.from.js), [`es.array.is-array`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.is-array.js), [`es.array.of`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.of.js), [`es.array.copy-within`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.copy-within.js), [`es.array.fill`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.fill.js), [`es.array.find`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.find.js), [`es.array.find-index`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.find-index.js), [`es.array.find-last`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.find-last.js), [`es.array.find-last-index`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.find-last-index.js), [`es.array.iterator`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.iterator.js), [`es.array.includes`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.includes.js), [`es.array.push`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.push.js), [`es.array.slice`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.slice.js), [`es.array.join`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.join.js), [`es.array.unshift`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.unshift.js), [`es.array.index-of`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.index-of.js), [`es.array.last-index-of`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.last-index-of.js), [`es.array.every`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.every.js), [`es.array.some`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.some.js), [`es.array.for-each`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.for-each.js), [`es.array.map`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.map.js), [`es.array.filter`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.filter.js), [`es.array.reduce`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.reduce.js), [`es.array.reduce-right`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.reduce-right.js), [`es.array.reverse`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.reverse.js), [`es.array.sort`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.sort.js), [`es.array.flat`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.flat.js), [`es.array.flat-map`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.flat-map.js), [`es.array.unscopables.flat`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.unscopables.flat.js), [`es.array.unscopables.flat-map`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.unscopables.flat-map.js), [`es.array.at`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.at.js), [`es.array.to-reversed`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.to-reversed.js), [`es.array.to-sorted`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.to-sorted.js), [`es.array.to-spliced`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.to-spliced.js), [`es.array.with`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.with.js).
```ts
@@ -2170,6 +2186,20 @@ class ArrayBuffer {
core-js/proposals/array-buffer-transfer
```
##### [`Error.isError`](https://github.com/tc39/proposal-is-error)[⬆](#index)
```ts
class Error {
static isError(value: any): boolean;
}
```
[*CommonJS entry points:*](#commonjs-api)
```
core-js/proposals/is-error
```
> [!WARNING]
> We have no bulletproof way to polyfill this `Error.isError` / check if the object is an error, so it's an enough naive implementation.
##### [`Float16` methods](https://github.com/tc39/proposal-float16array)[⬆](#index)
```ts
class DataView {
@@ -2643,32 +2673,6 @@ core-js(-pure)/actual|full/symbol/metadata
core-js(-pure)/actual|full/function/metadata
```
##### [`Error.isError`](https://github.com/tc39/proposal-is-error)[⬆](#index)
Module [`esnext.error.is-error`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.error.is-error.js)
```ts
class Error {
static isError(value: any): boolean;
}
```
[*CommonJS entry points:*](#commonjs-api)
```
core-js/proposals/is-error
core-js(-pure)/actual|full/error/is-error
```
[*Example*](https://tinyurl.com/23nauwoz):
```js
Error.isError(new Error('error')); // => true
Error.isError(new TypeError('error')); // => true
Error.isError(new DOMException('error')); // => true
Error.isError(null); // => false
Error.isError({}); // => false
Error.isError(Object.create(Error.prototype)); // => false
```
> [!WARNING]
> We have no bulletproof way to polyfill this method / check if the object is an error, so it's an enough naive implementation.
#### Stage 2.7 proposals[⬆](#index)
[*CommonJS entry points:*](#commonjs-api)
```
+12 -9
View File
@@ -139,6 +139,15 @@ export const data = {
rhino: '1.8.0',
safari: '15.0',
},
'es.error.is-error': {
// early WebKit implementation bug
// https://github.com/oven-sh/bun/issues/15821
// bun: '1.1.39',
chrome: '134',
firefox: '138',
// https://github.com/nodejs/node/issues/58134
node: false,
},
'es.error.to-string': {
chrome: '33',
firefox: '11',
@@ -2389,15 +2398,8 @@ export const data = {
chrome: '136', // '134', // '133',
deno: '2.2.10',
},
'esnext.error.is-error': {
// early WebKit implementation bug
// https://github.com/oven-sh/bun/issues/15821
// bun: '1.1.39',
chrome: '134',
firefox: '138',
// https://github.com/nodejs/node/issues/58134
node: false,
},
// TODO: Remove from `core-js@4`
'esnext.error.is-error': null,
'esnext.function.demethodize': {
},
'esnext.function.is-callable': {
@@ -3081,6 +3083,7 @@ export const renamed = new Map([
['esnext.aggregate-error', 'es.aggregate-error'],
['esnext.data-view.get-float16', 'es.data-view.get-float16'],
['esnext.data-view.set-float16', 'es.data-view.set-float16'],
['esnext.error.is-error', 'es.error.is-error'],
['esnext.global-this', 'es.global-this'],
['esnext.iterator.constructor', 'es.iterator.constructor'],
['esnext.iterator.drop', 'es.iterator.drop'],
@@ -283,4 +283,7 @@ export default {
'es.math.f16round',
'es.regexp.escape',
],
3.43: [
'es.error.is-error',
],
};
+2 -3
View File
@@ -1,6 +1,5 @@
'use strict';
require('../../modules/es.object.create');
var parent = require('../../stable/error/is-error');
require('../../modules/esnext.error.is-error');
var path = require('../../internals/path');
module.exports = path.Error.isError;
module.exports = parent;
+1
View File
@@ -1,5 +1,6 @@
'use strict';
require('../../modules/es.error.cause');
require('../../modules/es.error.is-error');
require('../../modules/es.error.to-string');
var path = require('../../internals/path');
+6
View File
@@ -0,0 +1,6 @@
'use strict';
require('../../modules/es.object.create');
require('../../modules/es.error.is-error');
var path = require('../../internals/path');
module.exports = path.Error.isError;
@@ -0,0 +1,36 @@
'use strict';
var $ = require('../internals/export');
var getBuiltIn = require('../internals/get-built-in');
var isObject = require('../internals/is-object');
var classof = require('../internals/classof');
var fails = require('../internals/fails');
var ERROR = 'Error';
var DOM_EXCEPTION = 'DOMException';
// eslint-disable-next-line es/no-object-setprototypeof, no-proto -- safe
var PROTOTYPE_SETTING_AVAILABLE = Object.setPrototypeOf || ({}).__proto__;
var DOMException = getBuiltIn(DOM_EXCEPTION);
var $Error = Error;
var $isError = $Error.isError;
var FORCED = !$isError || !PROTOTYPE_SETTING_AVAILABLE || fails(function () {
// Bun, isNativeError-based implementations, some buggy structuredClone-based implementations, etc.
// https://github.com/oven-sh/bun/issues/15821
return (DOMException && !$isError(new DOMException(DOM_EXCEPTION))) ||
// structuredClone-based implementations
// eslint-disable-next-line es/no-error-cause -- detection
!$isError(new $Error(ERROR, { cause: function () { /* empty */ } })) ||
// instanceof-based and FF Error#stack-based implementations
$isError(getBuiltIn('Object', 'create')($Error.prototype));
});
// `Error.isError` method
// https://github.com/tc39/proposal-is-error
$({ target: 'Error', stat: true, sham: true, forced: FORCED }, {
isError: function isError(arg) {
if (!isObject(arg)) return false;
var tag = classof(arg);
return tag === ERROR || tag === DOM_EXCEPTION;
}
});
@@ -1,36 +1,3 @@
'use strict';
var $ = require('../internals/export');
var getBuiltIn = require('../internals/get-built-in');
var isObject = require('../internals/is-object');
var classof = require('../internals/classof');
var fails = require('../internals/fails');
var ERROR = 'Error';
var DOM_EXCEPTION = 'DOMException';
// eslint-disable-next-line es/no-object-setprototypeof, no-proto -- safe
var PROTOTYPE_SETTING_AVAILABLE = Object.setPrototypeOf || ({}).__proto__;
var DOMException = getBuiltIn(DOM_EXCEPTION);
var $Error = Error;
var $isError = $Error.isError;
var FORCED = !$isError || !PROTOTYPE_SETTING_AVAILABLE || fails(function () {
// Bun, isNativeError-based implementations, some buggy structuredClone-based implementations, etc.
// https://github.com/oven-sh/bun/issues/15821
return (DOMException && !$isError(new DOMException(DOM_EXCEPTION))) ||
// structuredClone-based implementations
// eslint-disable-next-line es/no-error-cause -- detection
!$isError(new $Error(ERROR, { cause: function () { /* empty */ } })) ||
// instanceof-based and FF Error#stack-based implementations
$isError(getBuiltIn('Object', 'create')($Error.prototype));
});
// `Error.isError` method
// https://github.com/tc39/proposal-is-error
$({ target: 'Error', stat: true, sham: true, forced: FORCED }, {
isError: function isError(arg) {
if (!isObject(arg)) return false;
var tag = classof(arg);
return tag === ERROR || tag === DOM_EXCEPTION;
}
});
// TODO: Remove from `core-js@4`
require('../modules/es.error.is-error');
@@ -0,0 +1,4 @@
'use strict';
var parent = require('../../es/error/is-error');
module.exports = parent;
-1
View File
@@ -5,7 +5,6 @@ require('../proposals/array-buffer-base64');
require('../proposals/array-from-async-stage-2');
require('../proposals/decorator-metadata-v2');
require('../proposals/explicit-resource-management');
require('../proposals/is-error');
require('../proposals/json-parse-with-source');
require('../proposals/math-sum');
// TODO: Obsolete versions, remove from `core-js@4`
+1
View File
@@ -8,6 +8,7 @@ require('../proposals/change-array-by-copy-stage-4');
// require('../proposals/error-cause');
require('../proposals/float16');
require('../proposals/global-this');
require('../proposals/is-error');
require('../proposals/iterator-helpers-stage-3-2');
require('../proposals/promise-all-settled');
require('../proposals/promise-any');
+6 -6
View File
@@ -419,6 +419,12 @@ GLOBAL.tests = {
return new Error('e', { cause: 7 }).cause === 7
&& !('cause' in Error.prototype);
},
'es.error.is-error': function () {
return PROTOTYPE_SETTING_AVAILABLE &&
(typeof DOMException != 'function' || Error.isError(new DOMException('DOMException'))) &&
Error.isError(new Error('Error', { cause: function () { /* empty */ } })) &&
!Error.isError(Object.create(Error.prototype));
},
'es.error.to-string': function () {
if (DESCRIPTORS_SUPPORT) {
// Chrome 32- incorrectly call accessor
@@ -1806,12 +1812,6 @@ GLOBAL.tests = {
'esnext.disposable-stack.constructor': function () {
return typeof DisposableStack == 'function';
},
'esnext.error.is-error': function () {
return PROTOTYPE_SETTING_AVAILABLE &&
(typeof DOMException != 'function' || Error.isError(new DOMException('DOMException'))) &&
Error.isError(new Error('Error', { cause: function () { /* empty */ } })) &&
!Error.isError(Object.create(Error.prototype));
},
'esnext.function.demethodize': function () {
return Function.prototype.demethodize;
},
+1 -1
View File
@@ -136,6 +136,7 @@ for (PATH of ['core-js-pure', 'core-js']) {
ok('from' in load(NS, 'array'));
ok(load(NS, 'array/splice')([1, 2, 3], 1, 2)[0] === 2);
ok(new (load(NS, 'error/constructor').Error)(1, { cause: 7 }).cause === 7);
ok(load(NS, 'error/is-error')(new Error()));
ok(typeof load(NS, 'error/to-string') == 'function');
ok(new (load(NS, 'error').Error)(1, { cause: 7 }).cause === 7);
ok(load(NS, 'math/acosh')(1) === 0);
@@ -697,7 +698,6 @@ for (PATH of ['core-js-pure', 'core-js']) {
ok(typeof load(NS, 'async-iterator/some') == 'function');
ok(typeof load(NS, 'async-iterator/take') == 'function');
ok(typeof load(NS, 'async-iterator/to-array') == 'function');
ok(load(NS, 'error/is-error')(new Error()));
ok(load(NS, 'function/metadata') === null);
ok(typeof load(NS, 'iterator/to-async') == 'function');
ok(load(NS, 'json/is-raw-json')({}) === false);
@@ -1,4 +1,4 @@
import isError from 'core-js-pure/actual/error/is-error';
import isError from 'core-js-pure/es/error/is-error';
import create from 'core-js-pure/es/object/create';
import AggregateError from 'core-js-pure/es/aggregate-error';
import SuppressedError from 'core-js-pure/actual/suppressed-error';