fix(web): close the SSE EventSource on pagehide (BUNYIP-380) #377

Merged
nrupard merged 2 commits from fix/BUNYIP-380-sse-pagehide-close into main 2026-07-18 17:22:35 +02:00
Owner

Summary

Closes the injected /v1/events EventSource on pagehide so server-rendered navigations no longer log the "connection was interrupted while the page was loading" console warning. Fixes BUNYIP-380.

Root cause

bunyip-web is server-rendered: every in-app navigation is a full page load. The departing page's long-lived EventSource is aborted mid-flight by the browser as the next document loads, so the browser logs "The connection to .../v1/events was interrupted while the page was loading" on every navigation. Harmless (the next page opens a fresh stream) but it clutters the console and can mask real errors.

Change

bunyip-web/src/views/layout.rs SSE_SUBSCRIBER: add window.addEventListener('pagehide',function(){try{es.close();}catch(e){}}); right after the EventSource is created, so the stream closes cleanly before the document unloads instead of being interrupted. es.close() is idempotent. No server change - the /v1/events handler is untouched - and CSP is script-src 'self' 'unsafe-inline', so the inline-script edit needs no hash/nonce update.

Scope note

The content.js:138 the element does not exist line reported alongside the warning is a browser extension content script, not bunyip - out of scope per the ticket.

Test

just check-container green (fmt + clippy + 104 tests). After deploy, verify in-app navigation no longer logs the /v1/events interrupted warning and that SSE still connects and delivers per-user events (BUNYIP-145 behaviour intact - the change only adds a close-on-unload).

## Summary Closes the injected `/v1/events` EventSource on `pagehide` so server-rendered navigations no longer log the "connection was interrupted while the page was loading" console warning. Fixes BUNYIP-380. ## Root cause bunyip-web is server-rendered: every in-app navigation is a full page load. The departing page's long-lived EventSource is aborted mid-flight by the browser as the next document loads, so the browser logs "The connection to .../v1/events was interrupted while the page was loading" on every navigation. Harmless (the next page opens a fresh stream) but it clutters the console and can mask real errors. ## Change `bunyip-web/src/views/layout.rs` `SSE_SUBSCRIBER`: add `window.addEventListener('pagehide',function(){try{es.close();}catch(e){}});` right after the EventSource is created, so the stream closes cleanly before the document unloads instead of being interrupted. `es.close()` is idempotent. No server change - the `/v1/events` handler is untouched - and CSP is `script-src 'self' 'unsafe-inline'`, so the inline-script edit needs no hash/nonce update. ## Scope note The `content.js:138 the element does not exist` line reported alongside the warning is a browser extension content script, not bunyip - out of scope per the ticket. ## Test `just check-container` green (fmt + clippy + 104 tests). After deploy, verify in-app navigation no longer logs the `/v1/events` interrupted warning and that SSE still connects and delivers per-user events (BUNYIP-145 behaviour intact - the change only adds a close-on-unload).
fix(web): close the SSE EventSource on pagehide (BUNYIP-380)
Some checks failed
E2E / Playwright against deployment (pull_request) Failing after 19s
Check / fmt + clippy + build + tests (pull_request) Successful in 18m48s
411d01be37
bunyip-web is server-rendered, so every in-app navigation is a full page load. The prior page's long-lived `/v1/events` EventSource was aborted mid-flight by the browser as the next document loaded, logging "The connection to .../v1/events was interrupted while the page was loading" on every navigation. Harmless (the next page opens a fresh stream) but it cluttered the console and could mask real errors while debugging.

Register a `pagehide` listener in the injected SSE shell that calls `es.close()` before the document unloads, so the stream closes gracefully instead of being interrupted. `es.close()` is idempotent, so closing an already-errored stream is harmless. The server `/v1/events` handler is unchanged; this is a client-lifecycle fix only.

The `content.js:138` line reported alongside the warning is a browser extension content script, not bunyip, and is out of scope.

check-container green (fmt + clippy + 104 tests).

#BUNYIP-380

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Merge branch 'main' into fix/BUNYIP-380-sse-pagehide-close
All checks were successful
E2E / Playwright against deployment (pull_request) Successful in 41s
Check / fmt + clippy + build + tests (pull_request) Successful in 30m57s
Create release / Create release from merged PR (pull_request) Has been skipped
f1d2e4ba71
nrupard scheduled this pull request to auto merge when all checks succeed 2026-07-18 16:52:19 +02:00
nrupard canceled auto merging this pull request when all checks succeed 2026-07-18 16:52:24 +02:00
nrupard scheduled this pull request to auto merge when all checks succeed 2026-07-18 16:52:29 +02:00
nrupard deleted branch fix/BUNYIP-380-sse-pagehide-close 2026-07-18 17:22:36 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/bunyip!377
No description provided.