fix(beacon): stop the processing spinner hanging forever (#28)

The torrent beacon's processing overlay was gated on WebTorrent's metadata-ready
callback (client.add/seed), which only fires once metadata arrives from peers. A
magnet with no live seeders never resolved it, so the spinner span forever, and a
torrent that emitted its own 'error' didn't always reach the client-level handler.

- beginProcessing() arms a 30s watchdog that drops the overlay and warns ("still
  searching for peers — it'll keep trying in the background") instead of hanging;
  the torrent stays in the table and keeps announcing.
- handleTorrentReady, the client error handler, and destroy() clear the watchdog.
- addMagnet/seedFiles wrap add/seed in try/catch and attach a per-torrent 'error'
  listener so bad/duplicate magnets fail visibly.
- Tests: tests/torrent/beacon-watchdog.test.mjs (JSDOM).

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
thePR0M3TH3ANandClaude Opus 4.8 committed 2026-06-24 21:57:11 -04:00
1 parent 1c256808ff
commit fdcf034464
4 files changed
+222 -15

No files matched your search

+20 -6
View File
@@ -516,12 +516,26 @@ SILENT one: `handleEventDetailsAction` only opened the modal `if (… && payload
- [ ] **VERIFY live**: click ⋯ → Event Details AND ⋯ → Popularity in the video
modal AND on a grid/channel card; both should open the correct video.
### 28. Beacon torrent app stuck — spinner never resolves (BUG)
- [ ] The torrent beacon app (`scripts/build:beacon` / `torrent/` integration) shows
a spinner that never goes away. Trace the beacon's init/connect path: what the
spinner is waiting on (tracker/handshake/WebTorrent ready), whether it errors
silently, and whether it's related to the vendored `webtorrent.min.js`
`null.fill` crash (#10). Make it either resolve or fail visibly.
### 28. Beacon torrent app stuck — spinner never resolves (BUG) — FIXED 2026-06-24
- [x] **Root cause:** the processing overlay (`torrent/app.js`) was gated on
WebTorrent's metadata-ready callback (`client.add(magnet, opts, cb)` /
`client.seed`). That callback only fires once metadata arrives from peers, so
a magnet with **no live seeders** never resolved it and the spinner span
forever — and a torrent that emits its own `'error'` (bad/duplicate magnet)
didn't always reach the client-level handler. (NOT the `null.fill` crash
(#10); the client constructs fine — this was a missing timeout/failure path.)
- [x] **Fix:** added a watchdog around the overlay. `beginProcessing()` arms a
30s `PROCESSING_TIMEOUT_MS` timer; if the op hasn't completed it drops the
overlay and warns ("still searching for peers — it'll keep trying in the
background") while the torrent stays in the table and keeps announcing.
`handleTorrentReady`, the client error handler, and `destroy()` all clear the
watchdog. `addMagnet`/`seedFiles` now wrap `add`/`seed` in try/catch and
attach a per-torrent `'error'` listener so bad magnets fail visibly.
- [x] **Tests:** `tests/torrent/beacon-watchdog.test.mjs` (JSDOM) — a no-peers
magnet drops the spinner + warns; a ready torrent resolves it and a stale
watchdog can't re-fire.
- [ ] **VERIFY live**: open the beacon, paste a dead magnet → spinner should clear
with a warning after ~30s instead of hanging; paste a live magnet → resolves.
### 29. Admin-whitelisted users bypass the Web-of-Trust (anti-abuse)
- [ ] When an admin **whitelists** a user, that user's content should **bypass the