diff --git a/test/v8/v8-module/main.cpp b/test/v8/v8-module/main.cpp index 76dd3c0120..88d01cecc4 100644 --- a/test/v8/v8-module/main.cpp +++ b/test/v8/v8-module/main.cpp @@ -248,6 +248,22 @@ void test_v8_object(const FunctionCallbackInfo &info) { return ok(info); } +void set_field_from_js(const FunctionCallbackInfo &info) { + Isolate *isolate = info.GetIsolate(); + Local context = isolate->GetCurrentContext(); + + Local obj = info[0].As(); + Local key = info[1]; + Local value = Number::New(isolate, 321.0); + Maybe ret = obj->Set(context, key, value); + LOG_EXPR(ret.IsJust()); + if (ret.IsJust()) { + LOG_EXPR(ret.ToChecked()); + } + + return ok(info); +} + void test_v8_array_new(const FunctionCallbackInfo &info) { Isolate *isolate = info.GetIsolate(); @@ -483,6 +499,7 @@ void initialize(Local exports, Local module, test_v8_string_write_utf8); NODE_SET_METHOD(exports, "test_v8_external", test_v8_external); NODE_SET_METHOD(exports, "test_v8_object", test_v8_object); + NODE_SET_METHOD(exports, "set_field_from_js", set_field_from_js); NODE_SET_METHOD(exports, "test_v8_array_new", test_v8_array_new); NODE_SET_METHOD(exports, "test_v8_object_template", test_v8_object_template); NODE_SET_METHOD(exports, "create_function_with_data", diff --git a/test/v8/v8-module/module.js b/test/v8/v8-module/module.js index b15152026b..b55b01a808 100644 --- a/test/v8/v8-module/module.js +++ b/test/v8/v8-module/module.js @@ -2,6 +2,7 @@ module.exports = debugMode => { const nativeModule = require(`./build/${debugMode ? "Debug" : "Release"}/v8tests`); return { ...nativeModule, + test_v8_global() { console.log(nativeModule.global_get()); nativeModule.global_set(123); @@ -12,6 +13,7 @@ module.exports = debugMode => { } console.log(JSON.stringify(nativeModule.global_get())); }, + test_v8_function_template() { const f = nativeModule.create_function_with_data(); if (process.isBun) { @@ -19,5 +21,52 @@ module.exports = debugMode => { } console.log(f()); }, + + test_v8_object_set_failure() { + const object = {}; + const key = { + toString() { + throw new Error("thrown by key.toString()"); + }, + }; + + try { + nativeModule.set_field_from_js(object, key); + console.log("no error while setting with key that throws in toString()"); + } catch (e) { + console.log(e.toString()); + } + + const setterThrows = new Proxy(object, { + set(obj, prop, value) { + throw new Error(`proxy setting ${prop} to ${value}`); + }, + }); + + try { + nativeModule.set_field_from_js(setterThrows, "xyz"); + console.log("no error while setting on Proxy that throws"); + } catch (e) { + console.log(e.toString()); + } + + console.log("after setting, object.xyz is", object.xyz); + + const onlyGetter = { + get foo() { + return 5; + }, + }; + + try { + nativeModule.set_field_from_js(onlyGetter, "foo"); + // apparently this is expected in node + console.log("no error while setting a key that only has a getter"); + } catch (e) { + console.log(e.toString()); + } + + console.log("after setting, onlyGetter.foo is", onlyGetter.foo); + }, }; }; diff --git a/test/v8/v8.test.ts b/test/v8/v8.test.ts index 9d27cdd952..acb189570f 100644 --- a/test/v8/v8.test.ts +++ b/test/v8/v8.test.ts @@ -139,6 +139,9 @@ describe("Object", () => { it("can create an object and set properties", () => { checkSameOutput("test_v8_object", []); }); + it("can handle failure in Set()", () => { + checkSameOutput("test_v8_object_set_failure", []); + }); }); describe("Array", () => { // v8::Array::New is broken as it still tries to reinterpret locals as JSValues