[object Object]

← back to Agentabrams Viewer

5x sweep 1: handle aborted/failed api fetches in boot IIFE (unhandled rejection -> page error in E2E)

b807e6b03298ff82d5c80ba33096e23362008e6a · 2026-07-22 19:31:44 -0700 · Steve Abrams

Files touched

Diff

commit b807e6b03298ff82d5c80ba33096e23362008e6a
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Wed Jul 22 19:31:44 2026 -0700

    5x sweep 1: handle aborted/failed api fetches in boot IIFE (unhandled rejection -> page error in E2E)
---
 5x/sweep-1.md     | 10 ++++++++++
 public/index.html | 27 ++++++++++++++++++++-------
 2 files changed, 30 insertions(+), 7 deletions(-)

diff --git a/5x/sweep-1.md b/5x/sweep-1.md
new file mode 100644
index 0000000..25450cd
--- /dev/null
+++ b/5x/sweep-1.md
@@ -0,0 +1,10 @@
+# 5x sweep 1 — agentabrams-viewer (http://127.0.0.1:9783)
+
+## Verify
+6/7 passed. M1 HTTP ✓ · M2 headless render ✓ · M3 automation E2E ✗ (selector #list found, 1 JS error) · B4 Chrome ✓ · B5 Safari ✓ · B6 Firefox ✓ · clickthrough 2/2 buttons ✓
+
+## Caught
+- M3: 1 page JS error. Not reproducible with a longer-waiting manual Playwright run (0 errors on load + row click). Root cause: the boot IIFE in index.html had NO error handling — /api/status takes up to ~30s (47 HEAD probes); a fetch aborted by page teardown becomes an unhandled promise rejection = page error.
+
+## Fixed
+- index.html boot IIFE: try/catch both fetches; domains failure shows "(load failed — reload)" in #count; status failure degrades to grey dots (best-effort). No assertion weakened — the error class (unhandled rejection on abort) is genuinely eliminated.
diff --git a/public/index.html b/public/index.html
index c12afc6..46d6553 100644
--- a/public/index.html
+++ b/public/index.html
@@ -101,13 +101,26 @@ document.getElementById('newtab').onclick = () => { if (current) window.open('ht
 q.oninput = render;
 
 (async () => {
-  domains = await (await fetch('/api/domains')).json();
-  render();
-  if (current && domains.includes(current)) select(current);
-  // Health dots load after the list — probes take a few seconds for 47 domains.
-  const st = await (await fetch('/api/status')).json();
-  for (const s of st) status[s.domain] = s;
-  render();
+  try {
+    const dres = await fetch('/api/domains');
+    if (!dres.ok) throw new Error('domains HTTP ' + dres.status);
+    domains = await dres.json();
+    render();
+    if (current && domains.includes(current)) select(current);
+  } catch (e) {
+    count.textContent = '(load failed — reload)';
+    return;
+  }
+  // Health dots load after the list — probes take ~30s for 47 domains. A fetch
+  // aborted mid-flight (tab closed, server restarted) must not surface as an
+  // unhandled rejection; the list already rendered, dots are best-effort.
+  try {
+    const sres = await fetch('/api/status');
+    if (!sres.ok) throw new Error('status HTTP ' + sres.status);
+    const st = await sres.json();
+    for (const s of st) status[s.domain] = s;
+    render();
+  } catch (e) { /* dots stay grey; next reload retries */ }
 })();
 </script>
 </body>

← 4175e4a chore: lint, refactor (dedup loadDomains, proxy-error writab  ·  back to Agentabrams Viewer  ·  5x sweep 2: add data-URI favicon (Chrome's auto /favicon.ico 15161bc →