Skip to content

Add Map#getOrInsert[Computed], Error.isError, Math.sumPrecise#34

Merged
frostney merged 2 commits into
mainfrom
es2026-features
Feb 23, 2026
Merged

Add Map#getOrInsert[Computed], Error.isError, Math.sumPrecise#34
frostney merged 2 commits into
mainfrom
es2026-features

Conversation

@frostney
Copy link
Copy Markdown
Owner

@frostney frostney commented Feb 22, 2026

…ath.sumPrecise`

Summary by CodeRabbit

  • New Features

    • Math.sumPrecise(): high-precision compensated summation
    • Error.isError(): static utility to detect Error instances
    • Map.prototype.getOrInsert() and getOrInsertComputed(): upsert APIs with eager/default and lazy-computed insertion
  • Tests

    • Comprehensive test suites added covering all new behaviors and edge cases
  • Documentation

    • Docs updated to document the new Math, Error, and Map APIs and test coverage counts

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 22, 2026

📝 Walkthrough

Walkthrough

Adds three built-in APIs: Math.sumPrecise (compensated summation), Error.isError (detect Error instances via error metadata), and Map.prototype.getOrInsert / getOrInsertComputed (upsert helpers). Implements runtime support, updates object error-data tracking, and adds comprehensive tests and docs.

Changes

Cohort / File(s) Summary
Documentation
docs/built-ins.md, README.md
Documented Math.sumPrecise, Error.isError, and Map.prototype.getOrInsert / getOrInsertComputed; updated proposal table and test count; removed Roadmap section.
Math implementation & registration
units/Goccia.Builtins.Math.pas
Added MathSumPrecise native method using Neumaier compensated summation, iterator protocol support, NaN/Infinity/-0 handling, and registered sumPrecise.
Error metadata & API
units/Goccia.Builtins.Globals.pas, units/Goccia.Values.ErrorHelper.pas, units/Goccia.Values.ObjectValue.pas
Introduced Error.isError native, added HasErrorData property to object values, ensured error objects set/clear error-data appropriately, and disabled propagation for DOMException.
Map prototype methods
units/Goccia.Values.MapValue.pas
Added MapGetOrInsert and MapGetOrInsertComputed implementations and registered prototype methods getOrInsert and getOrInsertComputed; handle lookup, insertion, lazy compute, and TypeError for non-callable callbacks.
Tests
tests/built-ins/Error/isError.js, tests/built-ins/Map/prototype/getOrInsert.js, tests/built-ins/Map/prototype/getOrInsertComputed.js, tests/built-ins/Math/sumPrecise.js
Added comprehensive test suites covering edge cases (NaN/infinity, empty iterables, non-iterables, callback behavior, NaN/object keys, and error-instance detection).

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • Add stack property for errors #23: Modifies error-object creation and metadata propagation (CreateErrorObject / error-data) which overlaps Error.isError and HasErrorData changes.

Poem

🐰 I hopped in with sums and a curious nose,
Counting floats true where the wild error goes.
I sniffed out errors, marked maps with a grin,
Seeds of new methods where changes begin.
Hooray—small paws, big features, let testing begin! 🎉

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: adding four new API methods (Map#getOrInsert, Map#getOrInsertComputed, Error.isError, Math.sumPrecise) across multiple built-in types, which aligns with the changeset's primary objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch es2026-features

Comment @coderabbitai help to get the list of available commands and usage tips.

@frostney frostney changed the title Add Map#getOrInsert, Map#getOrInsertComputed, Error.isError, `M… Add Map#getOrInsert[Computed], Error.isError, Math.sumPrecise Feb 23, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
tests/built-ins/Error/isError.js (1)

6-6: Consider adding GocciaScript feature gate for consistency.

The Map.prototype.getOrInsert and Map.prototype.getOrInsertComputed tests use describe.runIf(isGocciaScript) to conditionally run tests in GocciaScript environments. This test file lacks that pattern.

If Error.isError is intended to be a GocciaScript-specific feature (ES2026 proposal), consider adding the feature gate for consistency:

💡 Suggested addition
+const isGocciaScript = typeof GocciaScript !== "undefined";
+
-describe("Error.isError", () => {
+describe.runIf(isGocciaScript)("Error.isError", () => {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/built-ins/Error/isError.js` at line 6, The test suite for Error.isError
should be gated behind the GocciaScript feature flag like other ES2026-specific
tests; wrap or replace the top-level describe("Error.isError", ...) with
describe.runIf(isGocciaScript)("Error.isError", ...) (or add a surrounding
conditional using isGocciaScript) so the tests only run when the feature is
enabled, using the same pattern as
Map.prototype.getOrInsert/Map.prototype.getOrInsertComputed and referencing
describe.runIf and isGocciaScript to locate where to change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/built-ins.md`:
- Around line 142-146: Update the Math.sumPrecise documentation to explicitly
state its behavior for non-iterable inputs: mention that
Math.sumPrecise(iterable) throws a TypeError when the provided argument is not
an iterable (e.g., null, undefined, numbers, plain objects), keeping this
alongside the existing contract lines about non-number elements and empty
iterables; refer to the Math.sumPrecise symbol in the sentence so readers can
find the behavior in the API docs.

In `@tests/built-ins/Math/sumPrecise.js`:
- Around line 56-67: Update the tests for Math.sumPrecise to assert TypeError
explicitly instead of a generic throw: replace the generic expect(...).toThrow()
calls in the "throws TypeError for non-number elements" and "throws TypeError
for non-iterable argument" tests with expect(...).toThrow(TypeError) (or the
equivalent explicit TypeError assertion) for each case touching Math.sumPrecise
so the test verifies the contract requires TypeError for invalid inputs.

---

Nitpick comments:
In `@tests/built-ins/Error/isError.js`:
- Line 6: The test suite for Error.isError should be gated behind the
GocciaScript feature flag like other ES2026-specific tests; wrap or replace the
top-level describe("Error.isError", ...) with
describe.runIf(isGocciaScript)("Error.isError", ...) (or add a surrounding
conditional using isGocciaScript) so the tests only run when the feature is
enabled, using the same pattern as
Map.prototype.getOrInsert/Map.prototype.getOrInsertComputed and referencing
describe.runIf and isGocciaScript to locate where to change.

Comment thread docs/built-ins.md Outdated
Comment thread tests/built-ins/Math/sumPrecise.js
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Feb 23, 2026

Benchmark Results

179 benchmarks · 🟢 62 improved · 🔴 20 regressed · 97 unchanged · avg +4.6%

arrays.js — 🟢 14 improved, 5 unchanged · avg +15.1%
Benchmark Base (ops/sec) PR (ops/sec) Change
Array.from length 100 13,991 14,608 +4.4%
Array.from 10 elements 161,025 228,332 🟢 +41.8%
Array.of 10 elements 198,300 300,765 🟢 +51.7%
spread into new array 242,644 302,674 🟢 +24.7%
map over 50 elements 11,482 12,955 🟢 +12.8%
filter over 50 elements 9,816 11,849 🟢 +20.7%
reduce sum 50 elements 12,274 12,500 +1.8%
forEach over 50 elements 9,764 10,853 🟢 +11.2%
find in 50 elements 13,166 14,718 🟢 +11.8%
sort 20 elements 10,501 10,745 +2.3%
flat nested array 93,034 106,151 🟢 +14.1%
flatMap 60,176 65,939 🟢 +9.6%
map inside map (5x5) 17,138 19,722 🟢 +15.1%
filter inside map (5x10) 5,353 6,291 🟢 +17.5%
reduce inside map (5x10) 6,164 6,860 🟢 +11.3%
forEach inside forEach (5x10) 5,683 6,005 +5.7%
find inside some (10x10) 3,492 3,893 🟢 +11.5%
map+filter chain nested (5x20) 2,363 2,780 🟢 +17.6%
reduce flatten (10x5) 6,203 6,243 +0.6%
classes.js — 🟢 4 improved, 11 unchanged · avg +4.9%
Benchmark Base (ops/sec) PR (ops/sec) Change
simple class new 103,007 113,118 🟢 +9.8%
class with defaults 81,090 84,920 +4.7%
50 instances via Array.from 4,930 5,064 +2.7%
instance method call 48,306 50,842 +5.3%
static method call 82,285 90,296 🟢 +9.7%
single-level inheritance 40,297 43,173 🟢 +7.1%
two-level inheritance 35,778 37,600 +5.1%
private field access 47,232 49,374 +4.5%
private methods 55,007 57,145 +3.9%
getter/setter access 54,219 59,149 🟢 +9.1%
static getter read 99,873 101,951 +2.1%
static getter/setter pair 69,733 70,256 +0.8%
inherited static getter 54,978 58,073 +5.6%
inherited static setter 59,013 61,255 +3.8%
inherited static getter with this binding 47,395 46,967 -0.9%
closures.js — 🟢 6 improved, 5 unchanged · avg +7.6%
Benchmark Base (ops/sec) PR (ops/sec) Change
closure over single variable 87,543 94,999 🟢 +8.5%
closure over multiple variables 98,504 107,798 🟢 +9.4%
nested closures 109,254 115,682 +5.9%
function as argument 76,957 83,619 🟢 +8.7%
function returning function 98,907 104,737 +5.9%
compose two functions 59,996 62,809 +4.7%
fn.call 138,728 141,346 +1.9%
fn.apply 94,837 106,382 🟢 +12.2%
fn.bind 116,835 125,676 🟢 +7.6%
recursive sum to 50 8,131 9,192 🟢 +13.1%
recursive tree traversal 14,320 15,213 +6.2%
collections.js — 🟢 1 improved, 11 unchanged · avg +2.7%
Benchmark Base (ops/sec) PR (ops/sec) Change
add 50 elements 5,902 6,077 +3.0%
has lookup (50 elements) 9,187 9,514 +3.6%
delete elements 26,192 27,825 +6.2%
forEach iteration 5,877 5,954 +1.3%
spread to array 13,124 13,458 +2.6%
deduplicate array 41,453 48,012 🟢 +15.8%
set 50 entries 4,434 4,502 +1.6%
get lookup (50 entries) 4,721 4,545 -3.7%
has check 4,827 4,722 -2.2%
delete entries 12,860 13,175 +2.4%
forEach iteration 3,647 3,656 +0.2%
keys/values/entries 4,743 4,804 +1.3%
destructuring.js — 🟢 12 improved, 2 unchanged · avg +18.2%
Benchmark Base (ops/sec) PR (ops/sec) Change
simple array destructuring 303,221 392,666 🟢 +29.5%
with rest element 191,779 274,833 🟢 +43.3%
with defaults 305,208 395,375 🟢 +29.5%
skip elements 308,956 401,841 🟢 +30.1%
nested array destructuring 154,007 172,340 🟢 +11.9%
swap variables 366,481 398,564 🟢 +8.8%
simple object destructuring 248,185 300,988 🟢 +21.3%
with defaults 286,073 365,441 🟢 +27.7%
with renaming 290,810 316,951 🟢 +9.0%
nested object destructuring 147,126 150,699 +2.4%
rest properties 165,081 191,984 🟢 +16.3%
object parameter 84,697 88,569 +4.6%
array parameter 99,889 110,768 🟢 +10.9%
mixed destructuring in map 11,959 13,060 🟢 +9.2%
fibonacci.js — 🟢 4 improved, 2 unchanged · avg +9.7%
Benchmark Base (ops/sec) PR (ops/sec) Change
recursive fib(15) 222 255 🟢 +14.6%
recursive fib(20) 20 23 🟢 +14.6%
iterative fib(20) via reduce 10,136 11,621 🟢 +14.7%
iterator fib(20) 7,416 8,042 🟢 +8.4%
iterator fib(20) via Iterator.from + take 8,405 8,593 +2.2%
iterator fib(20) last value via reduce 7,003 7,258 +3.6%
iterators.js — 🟢 10 improved, 10 unchanged · avg +5.1%
Benchmark Base (ops/sec) PR (ops/sec) Change
Iterator.from({next}).toArray() — 20 elements 9,475 10,695 🟢 +12.9%
Iterator.from({next}).toArray() — 50 elements 4,057 4,561 🟢 +12.4%
spread pre-wrapped iterator — 20 elements 9,550 10,568 🟢 +10.7%
Iterator.from({next}).forEach — 50 elements 3,133 3,381 🟢 +7.9%
Iterator.from({next}).reduce — 50 elements 3,181 3,433 🟢 +7.9%
wrap array iterator 62,927 70,076 🟢 +11.4%
wrap plain {next()} object 6,532 7,075 🟢 +8.3%
map + toArray (50 elements) 2,770 3,057 🟢 +10.3%
filter + toArray (50 elements) 2,834 3,052 🟢 +7.7%
take(10) + toArray (50 element source) 15,605 16,420 +5.2%
drop(40) + toArray (50 element source) 3,923 4,190 +6.8%
chained map + filter + take (100 element source) 5,035 5,456 🟢 +8.4%
some + every (50 elements) 1,846 1,884 +2.1%
find (50 elements) 3,904 3,889 -0.4%
array.values().map().filter().toArray() 3,535 3,668 +3.8%
array.values().take(5).toArray() 18,938 18,663 -1.5%
array.values().drop(45).toArray() 11,256 11,392 +1.2%
map.entries() chained helpers 3,742 3,523 -5.9%
set.values() chained helpers 6,207 6,174 -0.5%
string iterator map + toArray 8,556 8,005 -6.4%
json.js — 🟢 3 improved, 17 unchanged · avg +2.2%
Benchmark Base (ops/sec) PR (ops/sec) Change
parse simple object 170,663 181,158 +6.1%
parse nested object 112,090 117,159 +4.5%
parse array of objects 58,727 62,533 +6.5%
parse large flat object 49,190 53,070 🟢 +7.9%
parse mixed types 73,620 77,624 +5.4%
stringify simple object 149,281 153,819 +3.0%
stringify nested object 83,018 81,402 -1.9%
stringify array of objects 16,805 17,171 +2.2%
stringify mixed types 65,666 70,737 🟢 +7.7%
reviver doubles numbers 34,616 36,685 +6.0%
reviver filters properties 32,589 31,960 -1.9%
reviver on nested object 43,582 40,736 -6.5%
reviver on array 21,998 21,601 -1.8%
replacer function doubles numbers 34,984 35,797 +2.3%
replacer function excludes properties 46,861 44,666 -4.7%
array replacer (allowlist) 92,804 96,624 +4.1%
stringify with 2-space indent 73,260 70,663 -3.5%
stringify with tab indent 73,268 74,354 +1.5%
parse then stringify 43,133 42,336 -1.8%
stringify then parse 16,344 17,874 🟢 +9.4%
jsx.jsx — 🔴 13 regressed, 8 unchanged · avg -7.3%
Benchmark Base (ops/sec) PR (ops/sec) Change
simple element 189,399 183,833 -2.9%
self-closing element 198,946 189,551 -4.7%
element with string attribute 165,681 159,645 -3.6%
element with multiple attributes 140,213 134,375 -4.2%
element with expression attribute 148,104 153,812 +3.9%
text child 192,689 178,249 🔴 -7.5%
expression child 186,465 164,897 🔴 -11.6%
mixed text and expression 174,915 155,733 🔴 -11.0%
nested elements (3 levels) 72,242 65,634 🔴 -9.1%
sibling children 52,874 47,879 🔴 -9.4%
component element 133,629 118,656 🔴 -11.2%
component with children 83,555 75,413 🔴 -9.7%
dotted component 111,154 100,943 🔴 -9.2%
empty fragment 189,702 166,080 🔴 -12.5%
fragment with children 50,422 47,316 -6.2%
spread attributes 95,799 88,943 🔴 -7.2%
spread with overrides 87,726 82,657 -5.8%
shorthand props 138,903 125,338 🔴 -9.8%
nav bar structure 24,311 21,895 🔴 -9.9%
card component tree 28,319 25,128 🔴 -11.3%
10 list items via Array.from 12,565 12,577 +0.1%
numbers.js — 🟢 6 improved, 5 unchanged · avg +7.2%
Benchmark Base (ops/sec) PR (ops/sec) Change
integer arithmetic 322,900 352,362 🟢 +9.1%
floating point arithmetic 343,991 378,912 🟢 +10.2%
number coercion 147,896 154,738 +4.6%
toFixed 86,429 93,635 🟢 +8.3%
toString 127,808 145,916 🟢 +14.2%
valueOf 178,452 195,925 🟢 +9.8%
toPrecision 118,698 120,018 +1.1%
Number.isNaN 232,127 245,372 +5.7%
Number.isFinite 230,664 241,923 +4.9%
Number.isInteger 210,907 231,744 🟢 +9.9%
Number.parseInt and parseFloat 186,808 190,207 +1.8%
objects.js — 🟢 2 improved, 🔴 1 regressed, 4 unchanged · avg +3.2%
Benchmark Base (ops/sec) PR (ops/sec) Change
create simple object 368,235 416,861 🟢 +13.2%
create nested object 193,021 199,374 +3.3%
create 50 objects via Array.from 9,634 8,614 🔴 -10.6%
property read 173,543 177,045 +2.0%
Object.keys 120,475 137,528 🟢 +14.2%
Object.entries 73,464 72,704 -1.0%
spread operator 157,153 159,397 +1.4%
promises.js — 12 unchanged · avg +0.2%
Benchmark Base (ops/sec) PR (ops/sec) Change
Promise.resolve(value) 406,517 429,396 +5.6%
new Promise(resolve => resolve(value)) 160,019 154,837 -3.2%
Promise.reject(reason) 410,888 416,168 +1.3%
resolve + then (1 handler) 133,510 141,675 +6.1%
resolve + then chain (3 deep) 53,317 53,400 +0.2%
resolve + then chain (10 deep) 17,150 17,619 +2.7%
reject + catch + then 79,130 75,708 -4.3%
resolve + finally + then 66,947 64,549 -3.6%
Promise.all (5 resolved) 26,026 25,343 -2.6%
Promise.race (5 resolved) 26,546 26,220 -1.2%
Promise.allSettled (5 mixed) 22,452 22,608 +0.7%
Promise.any (5 mixed) 26,779 26,960 +0.7%
strings.js — 🔴 6 regressed, 5 unchanged · avg -6.4%
Benchmark Base (ops/sec) PR (ops/sec) Change
string concatenation 369,296 322,122 🔴 -12.8%
template literal 372,449 390,954 +5.0%
string repeat 352,551 365,694 +3.7%
split and join 132,999 119,107 🔴 -10.4%
indexOf and includes 145,387 135,671 -6.7%
toUpperCase and toLowerCase 220,999 203,345 🔴 -8.0%
slice and substring 120,502 121,182 +0.6%
trim operations 168,605 147,126 🔴 -12.7%
replace and replaceAll 180,845 151,962 🔴 -16.0%
startsWith and endsWith 115,683 112,413 -2.8%
padStart and padEnd 174,006 155,499 🔴 -10.6%

Measured on ubuntu-latest x64. Changes within ±7% are considered insignificant.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
docs/built-ins.md (1)

454-455: Consider expanding the Map upsert methods documentation.

The current documentation is brief but functional. For better developer experience, consider adding details about:

  • Return values (does getOrInsert return the existing value when key is present, or the default?)
  • Callback signature for getOrInsertComputed (is the key passed as an argument?)
  • Error handling (what happens if the callback throws?)
  • Mutation semantics (clarify these are mutating operations)
📝 Example expanded documentation
-| `map.getOrInsert(key, default)` | Return value for key if present; otherwise insert default and return it (TC39 proposal-upsert) |
-| `map.getOrInsertComputed(key, cb)` | Return value for key if present; otherwise call `cb(key)`, insert result, and return it (TC39 proposal-upsert) |
+| `map.getOrInsert(key, default)` | Return the value for `key` if present; otherwise insert `default` as the value for `key` and return `default`. Mutates the map. (TC39 proposal-upsert) |
+| `map.getOrInsertComputed(key, cb)` | Return the value for `key` if present; otherwise call `cb(key)`, insert the result as the value for `key`, and return it. Mutates the map. Throws if `cb` is not callable or if `cb` throws. (TC39 proposal-upsert) |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/built-ins.md` around lines 454 - 455, Update the Map upsert method docs
for `map.getOrInsert(key, default)` and `map.getOrInsertComputed(key, cb)` to
explicitly state that `getOrInsert` returns the existing value if the key is
present and otherwise inserts and returns the provided default; that
`getOrInsertComputed` receives the key as its single argument (`cb(key)`), its
return value is inserted and returned; clarify that both methods mutate the Map
in-place; describe error behavior (if `cb` throws, no insertion occurs and the
exception propagates); and add a brief usage example showing both success and
error cases to make semantics clear.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/built-ins.md`:
- Around line 326-331: Update the docs for Error.isError to reflect the actual
brand-check used by the implementation: change the description for
Error.isError(arg) to state it returns true when arg has the internal
[[ErrorData]] slot (per ES2026 §20.5.2.1) rather than saying its prototype chain
includes Error.prototype, and mention this is a resilient brand check that
cannot be spoofed.

---

Nitpick comments:
In `@docs/built-ins.md`:
- Around line 454-455: Update the Map upsert method docs for
`map.getOrInsert(key, default)` and `map.getOrInsertComputed(key, cb)` to
explicitly state that `getOrInsert` returns the existing value if the key is
present and otherwise inserts and returns the provided default; that
`getOrInsertComputed` receives the key as its single argument (`cb(key)`), its
return value is inserted and returned; clarify that both methods mutate the Map
in-place; describe error behavior (if `cb` throws, no insertion occurs and the
exception propagates); and add a brief usage example showing both success and
error cases to make semantics clear.

Comment thread docs/built-ins.md
Comment on lines +326 to +331
**Static methods:**

| Method | Description |
|--------|-------------|
| `Error.isError(arg)` | Returns `true` if `arg` is an Error instance (prototype chain includes `Error.prototype`), `false` otherwise (ES2026) |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# Find the Error.isError implementation
rg -n 'ErrorIsError|error.*isError' -i --type=pascal

# Search in builtins for Error methods
fd -e pas | xargs grep -l 'Error' | grep -i builtin

# Look for Error object creation and methods
rg -n 'class Error|Error.*method' -i --type=pascal

Repository: frostney/GocciaScript

Length of output: 4024


🏁 Script executed:

# Read the ErrorIsError implementation
sed -n '202,220p' units/Goccia.Builtins.Globals.pas

Repository: frostney/GocciaScript

Length of output: 799


🏁 Script executed:

# Verify HasErrorData property in TGocciaObjectValue
rg -n 'HasErrorData|FErrorData' units/Goccia.Values.ObjectValue.pas | head -20

Repository: frostney/GocciaScript

Length of output: 173


Update Error.isError() documentation to match implementation.

The documentation describes the method as checking if arg's "prototype chain includes Error.prototype", but the actual implementation uses [[ErrorData]] internal slot for brand checking (as per ES2026 §20.5.2.1). Update line 330 to clarify that it returns true if arg has the [[ErrorData]] internal slot, which is the reliable brand check mechanism used in the codebase and cannot be spoofed.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/built-ins.md` around lines 326 - 331, Update the docs for Error.isError
to reflect the actual brand-check used by the implementation: change the
description for Error.isError(arg) to state it returns true when arg has the
internal [[ErrorData]] slot (per ES2026 §20.5.2.1) rather than saying its
prototype chain includes Error.prototype, and mention this is a resilient brand
check that cannot be spoofed.

@frostney frostney merged commit 9dd70ed into main Feb 23, 2026
4 checks passed
@frostney frostney deleted the es2026-features branch February 23, 2026 00:11
@frostney frostney added the new feature New feature or request label Apr 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

new feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant