From 36b41616b0dbc715af0cd8b75c355b6c33fd4e2a Mon Sep 17 00:00:00 2001 From: min Date: Tue, 9 Jun 2026 10:28:32 +0300 Subject: [PATCH] =?UTF-8?q?fix(lua):=20=D0=BF=D1=80=D1=8F=D0=BC=D0=BE?= =?UTF-8?q?=D0=B9=20=D0=B2=D1=8B=D0=B7=D0=BE=D0=B2=20h.fn()=20=D0=B2=20JS?= =?UTF-8?q?=20=D0=B2=D0=BC=D0=B5=D1=81=D1=82=D0=BE=20=D0=BF=D0=B5=D1=80?= =?UTF-8?q?=D0=B5=D0=B4=D0=B0=D1=87=D0=B8=20=D0=B2=20Lua?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Не передаём JS-обёртку Lua-функции обратно в Lua через luaDrainHandler — это создавало wasmoon Promise-detection crash на null.then. Прямой h.fn(...args) → wasmoon вернёт Promise → .catch ловим. --- src/editor/engine/lua/RobloxShim.js | 30 ++++++++++++----------------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/src/editor/engine/lua/RobloxShim.js b/src/editor/engine/lua/RobloxShim.js index 6a8bc07..cb71593 100644 --- a/src/editor/engine/lua/RobloxShim.js +++ b/src/editor/engine/lua/RobloxShim.js @@ -1857,27 +1857,22 @@ export function registerRobloxShim(lua, opts) { // Запускаем каждый в своей coroutine — wait() внутри безопасен. if (_pendingHandlerQueue.length > 0) { const queue = _pendingHandlerQueue.splice(0, _pendingHandlerQueue.length); - // eslint-disable-next-line no-console - console.warn(`[handler-drain] draining ${queue.length} handlers`); for (const h of queue) { try { - const a = h.args || []; - // wasmoon-функция возвращает Promise. Если внутри Lua - // вернулся nil — wasmoon упадёт на .then(null). Ловим - // через .catch + try-catch синхронно. - let result; - if (a.length === 0) result = luaDrainHandler(h.fn); - else if (a.length === 1) result = luaDrainHandler(h.fn, a[0]); - else if (a.length === 2) result = luaDrainHandler(h.fn, a[0], a[1]); - else if (a.length === 3) result = luaDrainHandler(h.fn, a[0], a[1], a[2]); - else result = luaDrainHandler(h.fn, a[0], a[1], a[2], a[3]); - // Подавляем Promise.then(null) error + // ПРЯМОЙ вызов JS-обёртки Lua-функции (без передачи fn + // обратно в Lua через luaDrainHandler — это создаёт + // wasmoon Promise-detection crash на null.then). + // wasmoon вернёт Promise — ловим через .catch. + const result = h.fn(...(h.args || [])); if (result && typeof result.then === 'function') { - result.catch(() => {}); + result.catch((err) => { + // eslint-disable-next-line no-console + console.warn('[handler-async-err]', err?.message || err); + }); } } catch (e) { // eslint-disable-next-line no-console - console.warn('[handler-drain-catch]', e?.message || e); + console.warn('[handler-sync-err]', e?.message || e); } } } @@ -1934,11 +1929,10 @@ export function registerRobloxShim(lua, opts) { const id = p.primId ?? p.target; const part = partById.get(Number(id)); if (!part) return; - // ДИАГНОСТИКА: пробуем сначала без аргумента — чтобы понять hrp ли виноват if (p.kind === 'touch' || p.kind === 'touched') { - part.Touched.Fire(); // БЕЗ hrp — тест + part.Touched.Fire(hrp); } else if (p.kind === 'untouch' || p.kind === 'untouched') { - part.TouchEnded.Fire(); + part.TouchEnded.Fire(hrp); } }, fireGlobalEvent(p) {