From a9554e132fbff23d452867c84aa01411581ad573 Mon Sep 17 00:00:00 2001 From: linuztx Date: Tue, 31 Mar 2026 08:49:15 +0800 Subject: [PATCH] fix: auto-reinstall corrupt node_modules and stop poll loop after repeated bridge failures _ensure_npm_install now verifies key package exists, not just node_modules dir. Wipes and reinstalls if corrupt. Poll loop stops after 5 consecutive bridge start failures instead of spamming errors and making A0 unusable. --- .../extensions/python/job_loop/_10_wa_poll.py | 17 +++++++++++++++++ .../helpers/bridge_manager.py | 8 +++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/plugins/_whatsapp_integration/extensions/python/job_loop/_10_wa_poll.py b/plugins/_whatsapp_integration/extensions/python/job_loop/_10_wa_poll.py index a9041fc1f..522cbf2e2 100644 --- a/plugins/_whatsapp_integration/extensions/python/job_loop/_10_wa_poll.py +++ b/plugins/_whatsapp_integration/extensions/python/job_loop/_10_wa_poll.py @@ -12,6 +12,7 @@ from helpers import files, plugins PLUGIN_NAME: str = "_whatsapp_integration" DEFAULT_INTERVAL: int = 3 MIN_INTERVAL: int = 2 +MAX_CONSECUTIVE_FAILURES: int = 5 # ------------------------------------------------------------------ @@ -45,6 +46,7 @@ async def _poll_loop() -> None: from plugins._whatsapp_integration.helpers.handler import poll_messages bridge_started = False + consecutive_failures = 0 try: while True: @@ -66,6 +68,7 @@ async def _poll_loop() -> None: PrintStyle.info(f"WhatsApp: config changed, restarting bridge") await bridge_manager.stop_bridge() bridge_started = False + consecutive_failures = 0 # Start bridge if needed if not bridge_started or not bridge_manager.is_process_alive(): @@ -73,8 +76,22 @@ async def _poll_loop() -> None: bridge_started = await bridge_manager.start_bridge( port, session_dir, cache_dir, mode=mode, ) + if bridge_started: + consecutive_failures = 0 + else: + consecutive_failures += 1 except Exception as e: + consecutive_failures += 1 PrintStyle.error(f"WhatsApp bridge start error: {format_error(e)}") + + if consecutive_failures >= MAX_CONSECUTIVE_FAILURES: + PrintStyle.error( + f"WhatsApp: bridge failed {consecutive_failures} times in a row, " + f"stopping poll loop. Disable and re-enable the plugin to retry." + ) + break + + if not bridge_started: await asyncio.sleep(10) continue diff --git a/plugins/_whatsapp_integration/helpers/bridge_manager.py b/plugins/_whatsapp_integration/helpers/bridge_manager.py index 6bb4c0c5b..e3c60263c 100644 --- a/plugins/_whatsapp_integration/helpers/bridge_manager.py +++ b/plugins/_whatsapp_integration/helpers/bridge_manager.py @@ -222,8 +222,14 @@ async def _check_http_up(port: int) -> bool: async def _ensure_npm_install() -> None: node_modules = os.path.join(BRIDGE_DIR, "node_modules") - if os.path.isdir(node_modules): + key_package = os.path.join(node_modules, "@whiskeysockets", "baileys") + if os.path.isdir(key_package): return + # Missing or corrupt node_modules — wipe and reinstall + if os.path.isdir(node_modules): + import shutil + PrintStyle.warning("WhatsApp: node_modules corrupt, reinstalling") + shutil.rmtree(node_modules, ignore_errors=True) PrintStyle.info("WhatsApp: installing bridge dependencies") proc = await asyncio.create_subprocess_exec( "npm", "install", "--production",