Private
Public Access
Harden the update-check pipeline against silent failures (#58)
checkForUpdate() was a bare `void registration?.update()` -- a failed fetch (most plausible right when it's triggered by a WS reconnect, i.e. the network just flapped from a backend restart) vanished with nothing caught or logged, leaving only the hourly interval as a fallback. Now logs the failure instead of swallowing it, and a third trigger checks for an update whenever a backgrounded tab becomes visible again, so a tab that misses both the reconnect-triggered check and the hourly timer still gets a chance the moment someone actually looks at it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { useEffect } from 'react'
|
||||
import { useRegisterSW } from 'virtual:pwa-register/react'
|
||||
import { checkForUpdate, setSwRegistration } from '../lib/swUpdate'
|
||||
import './UpdateBanner.css'
|
||||
@@ -26,6 +27,21 @@ export function UpdateBanner() {
|
||||
},
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
// #58: a third trigger, alongside WS-reconnect and the hourly interval
|
||||
// above -- a tab backgrounded across a deploy gets checked the moment
|
||||
// someone actually looks at it again, rather than waiting on whichever
|
||||
// of those two happens to land first. Cheap insurance against either
|
||||
// one missing its moment (e.g. the reconnect-triggered check landing
|
||||
// during the same network blip that caused the reconnect, and failing
|
||||
// -- see checkForUpdate's own comment).
|
||||
function handleVisibilityChange() {
|
||||
if (document.visibilityState === 'visible') checkForUpdate()
|
||||
}
|
||||
document.addEventListener('visibilitychange', handleVisibilityChange)
|
||||
return () => document.removeEventListener('visibilitychange', handleVisibilityChange)
|
||||
}, [])
|
||||
|
||||
if (!needRefresh) return null
|
||||
|
||||
return (
|
||||
|
||||
@@ -10,5 +10,15 @@ export function setSwRegistration(reg: ServiceWorkerRegistration): void {
|
||||
}
|
||||
|
||||
export function checkForUpdate(): void {
|
||||
void registration?.update()
|
||||
// #58: this used to be a bare `void registration?.update()` -- if the
|
||||
// fetch failed (most plausible right when it's triggered by a WS
|
||||
// reconnect, i.e. the network just flapped from a backend restart), the
|
||||
// rejection vanished with nothing to catch it and nothing logged. The
|
||||
// only other trigger was an hourly interval, so a client that hit this
|
||||
// at the wrong moment could sit stale for up to an hour with zero trace
|
||||
// of why. This doesn't fix a bad network, but it stops the failure from
|
||||
// being silent, and callers still don't need to handle anything.
|
||||
registration?.update().catch((err: unknown) => {
|
||||
console.error('Service worker update check failed', err)
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user