From 2feecbfe4fd01e823613b24802b297569817bfec Mon Sep 17 00:00:00 2001 From: Stanislaw Grams Date: Sun, 8 Feb 2026 22:57:19 +0100 Subject: [PATCH] [fix](trx-frontend-http): fix decode SSE status detection Replace HEAD probe with EventSource readyState check to properly detect 404 vs connection drop. HEAD requests to SSE endpoints may not behave reliably across all setups. Co-Authored-By: Claude Opus 4.6 Signed-off-by: Stanislaw Grams --- .../trx-frontend-http/assets/web/app.js | 52 +++++++++---------- 1 file changed, 24 insertions(+), 28 deletions(-) diff --git a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/app.js b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/app.js index 8904bd4..2ca326e 100644 --- a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/app.js +++ b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/app.js @@ -1133,37 +1133,33 @@ function updateDecodeStatus(text) { } function connectDecode() { if (decodeSource) { decodeSource.close(); } - // Probe first to distinguish 404 from real SSE errors - fetch("/decode", { method: "HEAD" }).then((r) => { - if (r.status === 404) { - updateDecodeStatus("Decode not available (audio disabled?)"); - setTimeout(connectDecode, 10000); - return; + decodeSource = new EventSource("/decode"); + decodeSource.onopen = () => { + decodeConnected = true; + updateDecodeStatus("Connected, listening for packets"); + }; + decodeSource.onmessage = (evt) => { + try { + const msg = JSON.parse(evt.data); + if (msg.type === "aprs" && window.onServerAprs) window.onServerAprs(msg); + if (msg.type === "cw" && window.onServerCw) window.onServerCw(msg); + } catch (e) { + // ignore parse errors } - decodeSource = new EventSource("/decode"); - decodeSource.onopen = () => { - decodeConnected = true; - updateDecodeStatus("Connected, listening for packets"); - }; - decodeSource.onmessage = (evt) => { - try { - const msg = JSON.parse(evt.data); - if (msg.type === "aprs" && window.onServerAprs) window.onServerAprs(msg); - if (msg.type === "cw" && window.onServerCw) window.onServerCw(msg); - } catch (e) { - // ignore parse errors - } - }; - decodeSource.onerror = () => { - decodeSource.close(); - decodeConnected = false; + }; + decodeSource.onerror = () => { + // readyState CLOSED (2) = server rejected (404/error), CONNECTING (0) = temporary drop + const wasClosed = decodeSource.readyState === 2; + decodeSource.close(); + decodeConnected = false; + if (wasClosed) { + updateDecodeStatus("Decode not available (check client audio config)"); + setTimeout(connectDecode, 10000); + } else { updateDecodeStatus("Decode disconnected, retrying…"); setTimeout(connectDecode, 5000); - }; - }).catch(() => { - updateDecodeStatus("Decode endpoint unreachable"); - setTimeout(connectDecode, 5000); - }); + } + }; } connectDecode();