From 818d9c9f90b5ba5480b3c16c8b8fb9f3238bfb51 Mon Sep 17 00:00:00 2001 From: Smittix Date: Thu, 26 Feb 2026 22:17:26 +0000 Subject: [PATCH] morse: fix stop timeout causing restart loop via checkStatus When the stop POST timed out (5s), lifecycle was set to 'idle' on error, allowing checkStatus to see running=true and reconnect SSE. Now: - stop .then() stays in 'stopping' on timeout/error instead of going idle - checkStatus skips reconnect when lifecycle is 'stopping' post-timeout but still transitions to idle when server confirms running=false - LOCAL_STOP_TIMEOUT_MS raised from 5s to 12s to match server cleanup time Co-Authored-By: Claude Opus 4.6 --- static/js/modes/morse.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/static/js/modes/morse.js b/static/js/modes/morse.js index 860d03d..94d191e 100644 --- a/static/js/modes/morse.js +++ b/static/js/modes/morse.js @@ -7,7 +7,7 @@ var MorseMode = (function () { var SETTINGS_KEY = 'intercept.morse.settings.v3'; var STATUS_POLL_MS = 5000; - var LOCAL_STOP_TIMEOUT_MS = 5000; + var LOCAL_STOP_TIMEOUT_MS = 12000; var START_TIMEOUT_MS = 60000; var state = { @@ -403,6 +403,9 @@ var MorseMode = (function () { appendDiagLine('[stop] still alive: ' + data.alive.join(', ')); } + if (!data || data.status === 'error') { + return data; // Stay in 'stopping' — let checkStatus resolve + } setLifecycle('idle'); setStatusText('Standby'); return data; @@ -422,9 +425,10 @@ var MorseMode = (function () { .then(function (data) { if (!data || typeof data !== 'object') return; // Guard against in-flight polls that were dispatched before stop - if (state.stopPromise || state.lifecycle === 'stopping') return; + if (state.stopPromise) return; if (data.running) { + if (state.lifecycle === 'stopping') return; // Don't override post-timeout stopping if (data.state === 'starting') { setLifecycle('starting'); } else if (data.state === 'stopping') {