diff --git a/src/silver/ops/coercion.h b/src/silver/ops/coercion.h index 8b09864..5aea603 100644 --- a/src/silver/ops/coercion.h +++ b/src/silver/ops/coercion.h @@ -462,15 +462,17 @@ static inline ant_value_t sv_op_with_put_var( if (sv_with_binding_is_unscopable(js, frame->with_obj, a, &out, &abrupt)) goto fallback; if (abrupt) return out; ant_value_t key = js_mkstr(js, a->str, a->len); - js_setprop(js, frame->with_obj, key, val); + ant_value_t set_result = js_setprop(js, frame->with_obj, key, val); + if (is_err(set_result)) return set_result; return js_mkundef(); } } fallback: - if (fb_kind == WITH_FB_GLOBAL) - setprop_interned(js, js->global, a->str, a->len, val); - else sv_with_fallback_put(vm, js, frame, fb_kind, fb_idx, val); + if (fb_kind == WITH_FB_GLOBAL) { + ant_value_t set_result = setprop_interned(js, js->global, a->str, a->len, val); + if (is_err(set_result)) return set_result; + } else sv_with_fallback_put(vm, js, frame, fb_kind, fb_idx, val); return js_mkundef(); } diff --git a/tests/test_with_proxy_write_delete.cjs b/tests/test_with_proxy_write_delete.cjs index d9c8436..67166b0 100644 --- a/tests/test_with_proxy_write_delete.cjs +++ b/tests/test_with_proxy_write_delete.cjs @@ -64,4 +64,44 @@ try { assert(propagated, "proxy with delete should propagate thrown delete errors"); +const throwingSetProxy = new Proxy({}, { + has(_target, key) { + return key === "x"; + }, + set() { + throw new Error("set boom"); + }, +}); + +propagated = false; +try { + with (throwingSetProxy) { + x = 3; + } +} catch (e) { + propagated = e.message === "set boom"; +} + +assert(propagated, "proxy with assignment should propagate thrown set errors"); + +Object.defineProperty(globalThis, "withGlobalSetterThrow", { + configurable: true, + set() { + throw new Error("global setter boom"); + }, +}); + +propagated = false; +try { + with ({}) { + withGlobalSetterThrow = 1; + } +} catch (e) { + propagated = e.message === "global setter boom"; +} finally { + delete globalThis.withGlobalSetterThrow; +} + +assert(propagated, "with global fallback assignment should propagate thrown setters"); + console.log("OK");