Fail closed when worker update status is unavailable

This commit is contained in:
Jonathan Sykes
2026-10-08 00:10:04 +08:00
parent 5d1e5ec791
commit 92404563b3
2 changed files with 9 additions and 0 deletions

View File

@@ -161,6 +161,9 @@
const reg = root.navigator && await root.navigator.serviceWorker.getRegistration(); const reg = root.navigator && await root.navigator.serviceWorker.getRegistration();
const worker = reg && (reg.waiting || reg.active); const worker = reg && (reg.waiting || reg.active);
const status = await askCacheStatus(worker); const status = await askCacheStatus(worker);
// Unknown protocol is a retryable failure, never an empty successful
// legacy refresh followed by a reload into the old persistent manifest.
if (worker && !status) throw new Error('Worker update status unavailable; try again');
if (status && status.assetSync) { if (status && status.assetSync) {
const result = await core.syncAssets(m,{cache,fetchFn:opts.fetchFn}); const result = await core.syncAssets(m,{cache,fetchFn:opts.fetchFn});
if (!reg.waiting) await core.commit(m,cache); if (!reg.waiting) await core.commit(m,cache);

View File

@@ -362,3 +362,9 @@ test('explicit playback override clears the worker guard and reloads once',async
assert.deepStrictEqual(messages,[{type:'PLAYING',value:false},{type:'SKIP_WAITING'}]); assert.deepStrictEqual(messages,[{type:'PLAYING',value:false},{type:'SKIP_WAITING'}]);
container.fireControllerChange();container.fireControllerChange();assert.equal(reloads,1); container.fireControllerChange();container.fireControllerChange();assert.equal(reloads,1);
}); });
test('an unanswered worker status cannot fall through to an empty legacy refresh',async()=>{
const vm=require('node:vm'),fs=require('node:fs');
const sandbox={AssetSyncCore:{CACHE:'ytplayer-assets'},navigator:{serviceWorker:{getRegistration:async()=>({active:{postMessage(){}}})}}};
vm.runInNewContext(fs.readFileSync(__dirname+'/sw-update.js','utf8'),sandbox);
await assert.rejects(sandbox.SwUpdate.refreshShellInPlace({cachesApi:{open:async()=>({}),keys:async()=>[]},fetchFn:async()=>({ok:true,json:async()=>({buildTag:'new'})}),isShellCache:()=>true}),/Worker update status unavailable/);
});