diff --git a/packages/codemode/interpreter-support.md b/packages/codemode/interpreter-support.md index 0f05feec1899..a3e3139c80bd 100644 --- a/packages/codemode/interpreter-support.md +++ b/packages/codemode/interpreter-support.md @@ -596,8 +596,8 @@ Nothing is exposed unless a host provides it; extension calls are not tool calls non-enumerable: an extension Error carries it, and this JSON form does not. Errors have no `stack`; the diagnostic carries a 1-based line and column in the submitted source instead. - [x] `instanceof` against any constructor with a `prototype`, including every built-in and `Function`. -- [ ] The derived error constructors inheriting from `Error`: `Object.getPrototypeOf(TypeError)` is - `Function.prototype` here, while `TypeError.prototype` does inherit from `Error.prototype`. +- [x] Derived error constructors extend `Error` itself: `Object.getPrototypeOf(TypeError) === Error`, so + `TypeError.isError` is inherited, and `TypeError.prototype` inherits from `Error.prototype`. - [x] Catchable user throws, runtime failures raised during interpreted evaluation, awaited tool failures, and awaited tool-call-limit failures; parse/compile failures, cooperative timeout, and output bounding remain outside program `catch`. diff --git a/packages/codemode/src/interpreter/errors.ts b/packages/codemode/src/interpreter/errors.ts index 075422b2edfd..55a98a75b36d 100644 --- a/packages/codemode/src/interpreter/errors.ts +++ b/packages/codemode/src/interpreter/errors.ts @@ -180,6 +180,9 @@ export const errorGlobal = (type: ErrorType, ctx: Interpreter) => { ["toString", 0, (thisValue) => errorToString(receiver(Obj, thisValue, "Error.prototype.toString"))], ]) methods(builtins, ctor, [["isError", 1, (_, args) => args[0] instanceof ErrorObj]]) + return ctor } + // Derived constructors extend Error itself, so its statics are inherited. The globals table creates Error first. + ctor.proto = get(builtins.Error, "constructor") as Obj return ctor } diff --git a/packages/codemode/test/parity.test.ts b/packages/codemode/test/parity.test.ts index 904bd1f17f5a..1aedf74f10f5 100644 --- a/packages/codemode/test/parity.test.ts +++ b/packages/codemode/test/parity.test.ts @@ -1461,3 +1461,19 @@ describe("structuredClone", () => { expect((await error(`structuredClone()`)).message).toContain("structuredClone requires 1 argument") }) }) + +describe("error constructor prototype chain", () => { + test("derived error constructors extend Error and inherit its statics", async () => { + expect( + await value(` + const derived = [TypeError, RangeError, SyntaxError, ReferenceError, EvalError, URIError, AggregateError] + return [ + derived.every((ctor) => Object.getPrototypeOf(ctor) === Error), + Object.getPrototypeOf(Error) === Function.prototype, + TypeError.isError(new RangeError("x")), + new TypeError("x") instanceof Error, + ] + `), + ).toEqual([true, true, true, true]) + }) +}) diff --git a/packages/codemode/test/test262/skipped.txt b/packages/codemode/test/test262/skipped.txt index 6269f3780eb3..f35efefd7cb7 100644 --- a/packages/codemode/test/test262/skipped.txt +++ b/packages/codemode/test/test262/skipped.txt @@ -207,12 +207,6 @@ language/expressions/equals/S11.9.1_A7.8.js # #1: ({valueOf: function() {return language/expressions/equals/S11.9.1_A7.9.js # #1: (true == {valueOf: function() {return 1}}) === true language/expressions/equals/S9.1_A1_T3.js # #1: var object = {valueOf: function() {return 1}, toString: function() {return 0}}; object + "" === built-ins/Object/freeze/throws-when-false.js # Unknown identifier 'Proxy'. -built-ins/Object/getPrototypeOf/15.2.3.2-2-12.js # Object.getPrototypeOf(EvalError) Expected SameValue(«», «Error») to be true -built-ins/Object/getPrototypeOf/15.2.3.2-2-13.js # Object.getPrototypeOf(RangeError) Expected SameValue(«», «Error») to be true -built-ins/Object/getPrototypeOf/15.2.3.2-2-14.js # Object.getPrototypeOf(ReferenceError) Expected SameValue(«», «Error») to be true -built-ins/Object/getPrototypeOf/15.2.3.2-2-15.js # Object.getPrototypeOf(SyntaxError) Expected SameValue(«», «Error») to be true -built-ins/Object/getPrototypeOf/15.2.3.2-2-16.js # Object.getPrototypeOf(TypeError) Expected SameValue(«», «Error») to be true -built-ins/Object/getPrototypeOf/15.2.3.2-2-17.js # Object.getPrototypeOf(URIError) Expected SameValue(«», «Error») to be true built-ins/Object/getPrototypeOf/15.2.3.2-2-2.js # … cannot be constructed: user-defined constructors and classes are not supported. built-ins/Object/isExtensible/15.2.3.13-2-24.js # … cannot be constructed: user-defined constructors and classes are not supported. built-ins/Object/isExtensible/15.2.3.13-2-25.js # … cannot be constructed: user-defined constructors and classes are not supported.