Skip to content

Commit 2d4eff2

Browse files
committed
add Error#toString polyfill
1 parent a163fd5 commit 2d4eff2

File tree

16 files changed

+101
-28
lines changed

16 files changed

+101
-28
lines changed

packages/core-js-compat/src/data.mjs

+6
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,12 @@ export const data = {
385385
safari: '3.1',
386386
rhino: '1.7.13',
387387
},
388+
'es.error.to-string': {
389+
chrome: '26',
390+
firefox: '11',
391+
ie: '8',
392+
safari: '8.0',
393+
},
388394
'es.escape': {
389395
chrome: '1',
390396
firefox: '1',

packages/core-js-compat/src/modules-by-versions.mjs

+1
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ export default {
113113
],
114114
'3.20': [
115115
'es.error.cause',
116+
'es.error.to-string',
116117
'es.aggregate-error.cause',
117118
'es.number.to-exponential',
118119
'esnext.array.group-by-map',
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
// empty

packages/core-js/es/error/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
require('../../modules/es.error.cause');
2+
require('../../modules/es.error.to-string');
23
var path = require('../../internals/path');
34

45
module.exports = path;
+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
require('../../modules/es.error.to-string');
2+
var toString = require('../../internals/error-to-string');
3+
4+
module.exports = toString;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
var parent = require('../../stable/error/to-string');
2+
3+
module.exports = parent;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
'use strict';
2+
var fails = require('../internals/fails');
3+
var anObject = require('../internals/an-object');
4+
var normalizeStringArgument = require('../internals/normalize-string-argument');
5+
6+
var nativeErrorToString = Error.prototype.toString;
7+
8+
// FF10-
9+
var INCORRECT_TO_STRING = fails(function () {
10+
return String(nativeErrorToString.call({ message: 1, name: 2 })) !== '2: 1';
11+
});
12+
13+
module.exports = INCORRECT_TO_STRING ? function toString() {
14+
var O = anObject(this);
15+
var name = normalizeStringArgument(O.name, 'Error');
16+
var message = normalizeStringArgument(O.message);
17+
return !name ? message : !message ? name : name + ': ' + message;
18+
} : nativeErrorToString;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
var redefine = require('../internals/redefine');
2+
var errorToString = require('../internals/error-to-string');
3+
4+
var ErrorPrototype = Error.prototype;
5+
6+
// `Error.prototype.toString` method fix
7+
// https://tc39.es/ecma262/#sec-error.prototype.tostring
8+
if (ErrorPrototype.toString !== errorToString) {
9+
redefine(ErrorPrototype, 'toString', errorToString);
10+
}

packages/core-js/modules/web.dom-exception.js

+15-27
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ var redefine = require('../internals/redefine');
1111
var hasOwn = require('../internals/has-own-property');
1212
var anInstance = require('../internals/an-instance');
1313
var anObject = require('../internals/an-object');
14-
var $toString = require('../internals/to-string');
14+
var errorToString = require('../internals/error-to-string');
15+
var normalizeStringArgument = require('../internals/normalize-string-argument');
1516
var setToStringTag = require('../internals/set-to-string-tag');
1617
var InternalStateModule = require('../internals/internal-state');
1718
var DESCRIPTORS = require('../internals/descriptors');
@@ -22,7 +23,6 @@ var DOM_EXCEPTION = 'DOMException';
2223
var HAS_STACK = 'stack' in Error(DOM_EXCEPTION);
2324
var NativeDOMException = global[DOM_EXCEPTION];
2425
var NativeDOMExceptionPrototype = NativeDOMException && NativeDOMException.prototype;
25-
var ErrorPrototype = Error.prototype;
2626
var setInternalState = InternalStateModule.set;
2727
var getInternalState = InternalStateModule.getterFor(DOM_EXCEPTION);
2828

@@ -54,19 +54,15 @@ var errors = {
5454
DataCloneError: { s: DATA_CLONE_ERR, c: 25, m: 1 }
5555
};
5656

57-
var normalize = function (argument, $default) {
58-
return argument === undefined ? $default : $toString(argument);
59-
};
60-
6157
var codeFor = function (name) {
6258
return hasOwn(errors, name) && errors[name].m ? errors[name].c : 0;
6359
};
6460

6561
var $DOMException = function DOMException() {
6662
anInstance(this, $DOMException, DOM_EXCEPTION);
6763
var argumentsLength = arguments.length;
68-
var message = normalize(argumentsLength < 1 ? undefined : arguments[0], '');
69-
var name = normalize(argumentsLength < 2 ? undefined : arguments[1], 'Error');
64+
var message = normalizeStringArgument(argumentsLength < 1 ? undefined : arguments[0]);
65+
var name = normalizeStringArgument(argumentsLength < 2 ? undefined : arguments[1], 'Error');
7066
var code = codeFor(name);
7167
setInternalState(this, {
7268
type: DOM_EXCEPTION,
@@ -86,7 +82,7 @@ var $DOMException = function DOMException() {
8682
}
8783
};
8884

89-
var $DOMExceptionPrototype = $DOMException.prototype = create(ErrorPrototype);
85+
var $DOMExceptionPrototype = $DOMException.prototype = create(Error.prototype);
9086

9187
var createGetterDescriptor = function (get) {
9288
return { enumerable: true, configurable: true, get: get };
@@ -108,19 +104,14 @@ defineProperty($DOMExceptionPrototype, 'constructor', createPropertyDescriptor(1
108104

109105
// FF36- DOMException is a function, but can't be constructed
110106
var INCORRECT_CONSTRUCTOR = fails(function () {
111-
return !new NativeDOMException();
107+
return !(new NativeDOMException() instanceof Error);
112108
});
113109

114110
// Safari 10.1 / Deno 1.6.3- DOMException.prototype.toString bug
115111
var INCORRECT_TO_STRING = INCORRECT_CONSTRUCTOR || fails(function () {
116112
return String(new DOMException(1, 2)) !== '2: 1';
117113
});
118114

119-
// FF10-
120-
var INCORRECT_ERROR_TO_STRING = INCORRECT_CONSTRUCTOR || fails(function () {
121-
return String(ErrorPrototype.toString.call({ message: 1, name: 2 })) !== '2: 1';
122-
});
123-
124115
// Deno 1.6.3- DOMException.prototype.code just missed
125116
var INCORRECT_CODE = INCORRECT_CONSTRUCTOR || fails(function () {
126117
return new NativeDOMException(1, 'DataCloneError').code !== 25;
@@ -142,19 +133,16 @@ $({ global: true, forced: FORCED_CONSTRUCTOR }, {
142133
var PolyfilledDOMException = path[DOM_EXCEPTION];
143134
var PolyfilledDOMExceptionPrototype = PolyfilledDOMException.prototype;
144135

145-
if (PolyfilledDOMException !== $DOMException ? INCORRECT_TO_STRING : INCORRECT_ERROR_TO_STRING) {
146-
redefine(PolyfilledDOMExceptionPrototype, 'toString', function toString() {
147-
var O = anObject(this);
148-
var name = normalize(O.name, 'Error');
149-
var message = normalize(O.message, '');
150-
return !name ? message : !message ? name : name + ': ' + message;
151-
});
152-
}
136+
if (NativeDOMException === PolyfilledDOMException) {
137+
if (INCORRECT_TO_STRING) {
138+
redefine(PolyfilledDOMExceptionPrototype, 'toString', errorToString);
139+
}
153140

154-
if (PolyfilledDOMException !== $DOMException && INCORRECT_CODE && DESCRIPTORS) {
155-
defineProperty(PolyfilledDOMExceptionPrototype, 'code', createGetterDescriptor(function () {
156-
return codeFor(anObject(this).name);
157-
}));
141+
if (INCORRECT_CODE && DESCRIPTORS) {
142+
defineProperty(PolyfilledDOMExceptionPrototype, 'code', createGetterDescriptor(function () {
143+
return codeFor(anObject(this).name);
144+
}));
145+
}
158146
}
159147

160148
for (var key in errors) if (hasOwn(errors, key)) {

packages/core-js/stable/dom-exception.js

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
require('../modules/es.error.to-string');
12
require('../modules/web.dom-exception');
23
var path = require('../internals/path');
34

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
var parent = require('../../es/error/to-string');
2+
3+
module.exports = parent;

packages/core-js/web/dom-exception.js

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
require('../modules/es.error.to-string');
12
require('../modules/web.dom-exception');
23
var path = require('../internals/path');
34

tests/commonjs-entries-content.mjs

+3
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ superset('core-js/es/array', /^es\.array\./);
3636
superset('core-js/es/array-buffer', /^es\.array-buffer\./);
3737
superset('core-js/es/data-view', /^es\.data-view\./);
3838
superset('core-js/es/date', /^es\.date\./);
39+
superset('core-js/es/error', /^es\.error\./);
3940
superset('core-js/es/function', /^es\.function\./);
4041
superset('core-js/es/json', /^es\.json\./);
4142
superset('core-js/es/map', /^es\.map/);
@@ -58,6 +59,7 @@ superset('core-js/stable/array-buffer', /^es\.array-buffer\./);
5859
superset('core-js/stable/data-view', /^es\.data-view\./);
5960
superset('core-js/stable/date', /^es\.date\./);
6061
superset('core-js/stable/dom-collections', /^web\.dom-collections\./);
62+
superset('core-js/stable/error', /^es\.error\./);
6163
superset('core-js/stable/function', /^es\.function\./);
6264
superset('core-js/stable/json', /^es\.json\./);
6365
superset('core-js/stable/map', /^es\.map/);
@@ -83,6 +85,7 @@ superset('core-js/features/bigint', /^(es|esnext)\.bigint\./);
8385
superset('core-js/features/data-view', /^(es|esnext)\.data-view\./);
8486
superset('core-js/features/date', /^(es|esnext)\.date\./);
8587
superset('core-js/features/dom-collections', /^web\.dom-collections\./);
88+
superset('core-js/features/error', /^es\.error\./);
8689
superset('core-js/features/function', /^(es|esnext)\.function\./);
8790
superset('core-js/features/iterator', /^(es|esnext)\.iterator\./);
8891
superset('core-js/features/json', /^(es|esnext)\.json\./);

tests/commonjs.mjs

+1-1
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ for (PATH of ['core-js-pure', 'core-js']) {
120120
ok('from' in load(NS, 'array'));
121121
ok(load(NS, 'array/splice')([1, 2, 3], 1, 2)[0] === 2);
122122
ok(load(NS, 'error/constructor').Error(1, { cause: 7 }).cause === 7);
123+
ok(typeof load(NS, 'error/to-string') === 'function');
123124
ok(load(NS, 'error').Error(1, { cause: 7 }).cause === 7);
124125
ok(load(NS, 'math/acosh')(1) === 0);
125126
ok(Object.is(load(NS, 'math/asinh')(-0), -0));
@@ -258,7 +259,6 @@ for (PATH of ['core-js-pure', 'core-js']) {
258259
ok(load(NS, 'json').stringify([1]) === '[1]');
259260
ok(load(NS, 'json/stringify')([1]) === '[1]');
260261
ok(load(NS, 'json/to-string-tag') === 'JSON');
261-
262262
ok(typeof load(NS, '/date/now')(new Date()) === 'number');
263263
const date = new Date();
264264
ok(load(NS, 'date/get-year')(date) === date.getFullYear() - 1900);

tests/compat/tests.js

+3
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,9 @@ GLOBAL.tests = {
501501
'es.date.to-string': function () {
502502
return new Date(NaN).toString() == 'Invalid Date';
503503
},
504+
'es.error.to-string': function () {
505+
return Error.prototype.toString.call({ message: 1, name: 2 }) !== '2: 1';
506+
},
504507
'es.escape': function () {
505508
return escape;
506509
},

tests/tests/es.error.to-string.js

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { STRICT } from '../helpers/constants';
2+
3+
QUnit.test('Error#toString', assert => {
4+
const { toString } = Error.prototype;
5+
assert.isFunction(toString);
6+
assert.arity(toString, 0);
7+
assert.name(toString, 'toString');
8+
assert.looksNative(toString);
9+
assert.nonEnumerable(Error.prototype, 'toString');
10+
assert.same(String(new Error('something')), 'Error: something');
11+
assert.same(String(new TypeError('something')), 'TypeError: something');
12+
assert.same(String(new Error()), 'Error');
13+
assert.same(toString.call({}), 'Error');
14+
assert.same(toString.call({ name: 'foo' }), 'foo');
15+
assert.same(toString.call({ message: 'bar' }), 'Error: bar');
16+
assert.same(toString.call({ name: '', message: 'bar' }), 'bar');
17+
assert.same(toString.call({ name: 'foo', message: 'bar' }), 'foo: bar');
18+
assert.same(toString.call({ name: 1, message: 2 }), '1: 2');
19+
20+
if (STRICT) {
21+
assert.throws(() => toString.call(7));
22+
assert.throws(() => toString.call('a'));
23+
assert.throws(() => toString.call(false));
24+
assert.throws(() => toString.call(null));
25+
assert.throws(() => toString.call(undefined));
26+
}
27+
28+
// assert.throws(() => toString.call({ name: Symbol() }), 'throws on symbol #1');
29+
// assert.throws(() => toString.call({ name: Symbol() }), 'throws on symbol #2');
30+
});

0 commit comments

Comments
 (0)