diff --git a/src/bun.js/bindings/bindings.cpp b/src/bun.js/bindings/bindings.cpp index ee42eaa398e0..23094e8e01c1 100644 --- a/src/bun.js/bindings/bindings.cpp +++ b/src/bun.js/bindings/bindings.cpp @@ -5285,10 +5285,11 @@ static void JSC__JSValue__forEachPropertyImpl(JSC::EncodedJSValue JSValue0, JSC: } JSC::PropertySlot slot(object, PropertySlot::InternalMethodType::Get); - if (!object->getPropertySlot(globalObject, property, slot)) - continue; + bool hasProperty = object->getPropertySlot(globalObject, property, slot); // Ignore exceptions from "Get" proxy traps. CLEAR_IF_EXCEPTION(scope); + if (!hasProperty) + continue; if ((slot.attributes() & PropertyAttribute::DontEnum) != 0) { if (property == propertyNames->underscoreProto @@ -5360,7 +5361,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 "getPrototypeOf" trap. + CLEAR_IF_EXCEPTION(scope); + iterating = proto ? proto.getObject() : nullptr; } } diff --git a/test/js/bun/util/inspect.test.js b/test/js/bun/util/inspect.test.js index 32a70af30183..9c3a884550c9 100644 --- a/test/js/bun/util/inspect.test.js +++ b/test/js/bun/util/inspect.test.js @@ -451,6 +451,46 @@ const fixture = [ }, }, ), + () => { + class Foo { + get bar() { + throw new Error("bar throws"); + } + } + const obj = new Foo(); + Object.setPrototypeOf(obj, new Proxy(Object.getPrototypeOf(obj), {})); + return obj; + }, + () => { + const obj = { x: 1 }; + Object.setPrototypeOf( + obj, + new Proxy( + { y: 2 }, + { + getPrototypeOf() { + throw new Error("getPrototypeOf throws"); + }, + }, + ), + ); + return obj; + }, + () => { + const obj = {}; + Object.setPrototypeOf( + obj, + new Proxy( + { y: 2 }, + { + get() { + throw new Error("get throws"); + }, + }, + ), + ); + return obj; + }, ]; describe("crash testing", () => {