From 01e1882cd400a5a87a44ed8f5ff4848c110857c4 Mon Sep 17 00:00:00 2001 From: meshcore-bot Date: Thu, 7 May 2026 06:53:47 +0000 Subject: [PATCH] fix(#1150): render error state on full-page node detail when API 404s MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In loadFullNode's catch path: - Update .node-full-title to 'Node not found — …' on 404 (or 'Failed to load node' on other errors), instead of leaving 'Loading…'. - Replace the body's bare text with a card showing the requested pubkey, a friendly explanation, a 'Back to Nodes' link (href='#/nodes'), and a 'Try again' button that re-invokes loadFullNode. Fixes the symptom from issue #1150 (header title stuck on 'Loading…') and adds the affordances called out in the recommended fix (back link + retry). Fixes #1150 --- public/nodes.js | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/public/nodes.js b/public/nodes.js index ab186cd1..89a22c9f 100644 --- a/public/nodes.js +++ b/public/nodes.js @@ -842,7 +842,40 @@ }); } catch (e) { - body.innerHTML = `
Failed to load node: ${e.message}
`; + // #1150: surface a real error state in BOTH the back-row title and the body + // when /api/nodes/{pubkey} returns 404 (or any failure). Otherwise the title + // stays "Loading…" forever and there's no link back to the Nodes list. + const msg = (e && e.message) || ''; + const is404 = /\b404\b/.test(msg) || /not\s*found/i.test(msg); + const titleEl = document.querySelector('.node-full-title'); + if (titleEl) { + titleEl.textContent = is404 + ? 'Node not found — ' + (pubkey || '').slice(0, 12) + '…' + : 'Failed to load node'; + } + const safePubkey = escapeHtml(pubkey || ''); + const headline = is404 ? 'Node not found' : 'Failed to load node'; + const detail = is404 + ? 'No node matched the requested public key on this instance. It may exist on another deployment, or it may have been evicted/blacklisted here.' + : 'The node detail API call failed: ' + escapeHtml(msg); + body.innerHTML = + '
' + + '
' + headline + '
' + + '
' + safePubkey + '
' + + '
' + detail + '
' + + '
' + + '← Back to Nodes' + + '' + + '
' + + '
'; + const retryBtn = document.getElementById('nodeRetryBtn'); + if (retryBtn) { + retryBtn.addEventListener('click', function () { + if (titleEl) titleEl.textContent = 'Loading…'; + body.innerHTML = '
Loading…
'; + loadFullNode(pubkey); + }); + } } }