diff --git a/src/jsc/bindings/bindings.cpp b/src/jsc/bindings/bindings.cpp index 22ac38063376..f4c7d880aefe 100644 --- a/src/jsc/bindings/bindings.cpp +++ b/src/jsc/bindings/bindings.cpp @@ -5444,7 +5444,10 @@ static void JSC__JSValue__forEachPropertyImpl(JSC::EncodedJSValue JSValue0, JSC: break; if (iterating == globalObject) break; - iterating = iterating->getPrototype(globalObject).getObject(); + JSValue proto = iterating->getPrototype(globalObject); + // Ignore exceptions from Proxy "getPrototype" trap. + CLEAR_IF_EXCEPTION(scope); + iterating = proto ? proto.getObject() : nullptr; } } diff --git a/src/jsc/bindings/napi.cpp b/src/jsc/bindings/napi.cpp index 54c289e47f51..085f2dcc351a 100644 --- a/src/jsc/bindings/napi.cpp +++ b/src/jsc/bindings/napi.cpp @@ -1834,7 +1834,9 @@ extern "C" napi_status napi_get_all_property_names( // Climb up the prototype chain to find inherited properties JSObject* current_object = object; while (!current_object->getOwnPropertyDescriptor(globalObject, key.toPropertyKey(globalObject), desc)) { - JSObject* proto = current_object->getPrototype(globalObject).getObject(); + JSValue protoValue = current_object->getPrototype(globalObject); + NAPI_RETURN_IF_EXCEPTION(env); + JSObject* proto = protoValue.getObject(); if (!proto) { break; } diff --git a/test/js/bun/util/inspect.test.js b/test/js/bun/util/inspect.test.js index 32a70af30183..8a6ffe5f4511 100644 --- a/test/js/bun/util/inspect.test.js +++ b/test/js/bun/util/inspect.test.js @@ -451,6 +451,32 @@ const fixture = [ }, }, ), + () => { + const proto = new Proxy( + {}, + { + getPrototypeOf() { + throw new Error("nope"); + }, + }, + ); + const obj = Object.create(proto); + obj[0] = 1; + return obj; + }, + () => { + const proto = new Proxy( + {}, + { + getPrototypeOf() { + throw new Error("nope"); + }, + }, + ); + const obj = Object.create(proto); + Object.defineProperty(obj, "x", { get: () => 1, enumerable: true, configurable: true }); + return obj; + }, ]; describe("crash testing", () => {