Skip to content

Commit 925ea9a

Browse files
committed
fix(docs-infra): print info to help debugging SW cache issue (#41106)
From time to time, an angular.io page fails to load due to requesting a file that cannot be found neither on the server nor in the cache. We believe this is caused by the browser's partially clearing a cache. See #28114 for more details. Some time ago, we introduced [SwUpdate#unrecoverable][1] to help work around this issue by [reloading the page][2] when such an error is detected. However, this issue still pops up occasionally (for example, #41073). In an attempt to help diagnose the issue, this commit prints more info regarding the SW state and cache content when this error occurs. It will result in something like the following being printed to the console: ``` ServiceWorker: activated Cache: ngsw:/:db:control (2 entries) - https://angular.io/assignments: {"f5f02035-ee1f-463c-946c-e8b85badca25":"5c95f89a85255a6fefb4045a20f751ef32b2f3a4"} - https://angular.io/latest: {"latest":"5c95f89a85255a6fefb4045a20f751ef32b2f3a4"} Cache: ngsw:/:5c95f89a85255a6fefb4045a20f751ef32b2f3a4:assets:app-shell:cache (24 entries) - https://angular.io/0-es2015.867022f8bb092ae1efb1.worker.js - https://angular.io/announcement-bar-announcement-bar-module-es2015.1b5b762c9c8837c770f8.js - https://angular.io/api-api-list-module-es2015.40a43cd22f50f64d63bb.js ... Cache: ngsw:/:db:ngsw:/:5c95f89a85255a6fefb4045a20f751ef32b2f3a4:assets:app-shell:meta (1 entries) - https://angular.io/https://fonts.gstatic.com/s/robotomono/v13/L0x5DF4xlVMF-BfR8bXMIjhLq3-cXbKD.woff2: {"ts":1615031956601,"used":true} If you see this error, please report an issue at https://github.com/angular/angular/issues/new?template=3-docs-bug.md including the above logs. ``` NOTE: This change increases the main bundle by 1649B (0.37%), but it can be reverted as soon as we gather enough info to diagnose the issue. [1]: https://angular.io/api/service-worker/SwUpdate#unrecoverable [2]: https://github.com/angular/angular/blob/c676ec1ce5d586d4bc46/aio/src/app/sw-updates/sw-updates.service.ts#L55-L61 PR Close #41106
1 parent e7ce857 commit 925ea9a

File tree

2 files changed

+72
-4
lines changed

2 files changed

+72
-4
lines changed

aio/src/app/layout/doc-viewer/doc-viewer.component.ts

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,10 +143,18 @@ export class DocViewerComponent implements OnDestroy {
143143
switchMap(() => this.swapViews(addTitleAndToc)),
144144
tap(() => this.docRendered.emit()),
145145
catchError(err => {
146-
const errorMessage = (err instanceof Error) ? err.stack : err;
146+
const errorMessage = `${(err instanceof Error) ? err.stack : err}`;
147147
this.logger.error(new Error(`[DocViewer] Error preparing document '${doc.id}': ${errorMessage}`));
148148
this.nextViewContainer.innerHTML = '';
149149
this.setNoIndex(true);
150+
151+
// TODO(gkalpak): Remove this once gathering debug info is no longer needed.
152+
if (/loading chunk \d+ failed/i.test(errorMessage)) {
153+
// Print some info to help with debugging.
154+
// (There is no reason to wait for this async call to complete before continuing.)
155+
printSwDebugInfo();
156+
}
157+
150158
return this.void$;
151159
}),
152160
);
@@ -244,3 +252,63 @@ export class DocViewerComponent implements OnDestroy {
244252
);
245253
}
246254
}
255+
256+
// Helpers
257+
/**
258+
* Print some info regarding the ServiceWorker and the caches contents to help debugging potential
259+
* issues with failing to find resources in the cache.
260+
* (See https://github.com/angular/angular/issues/28114.)
261+
*/
262+
async function printSwDebugInfo(): Promise<void> {
263+
console.log(`\nServiceWorker: ${navigator.serviceWorker?.controller?.state ?? 'N/A'}`);
264+
265+
if (typeof caches === 'undefined') {
266+
console.log('\nCaches: N/A');
267+
} else {
268+
const allCacheNames = await caches.keys();
269+
const swCacheNames = allCacheNames.filter(name => name.startsWith('ngsw:/:'));
270+
271+
await findCachesAndPrintEntries(swCacheNames, 'db:control', true, ['manifests']);
272+
await findCachesAndPrintEntries(swCacheNames, 'assets:app-shell:cache', false);
273+
await findCachesAndPrintEntries(swCacheNames, 'assets:app-shell:meta', true);
274+
}
275+
276+
console.warn(
277+
'\nIf you see this error, please report an issue at ' +
278+
'https://github.com/angular/angular/issues/new?template=3-docs-bug.md including the above logs.');
279+
280+
// Internal helpers
281+
async function findCachesAndPrintEntries(
282+
swCacheNames: string[], nameSuffix: string, includeValues: boolean,
283+
ignoredKeys: string[] = []): Promise<void> {
284+
const cacheNames = swCacheNames.filter(name => name.endsWith(nameSuffix));
285+
286+
for (const cacheName of cacheNames) {
287+
const cacheEntries = await getCacheEntries(cacheName, includeValues, ignoredKeys);
288+
await printCacheEntries(cacheName, cacheEntries);
289+
}
290+
}
291+
292+
async function getCacheEntries(
293+
name: string, includeValues: boolean,
294+
ignoredKeys: string[] = []): Promise<{key: string, value?: object}[]> {
295+
const ignoredUrls = new Set(ignoredKeys.map(key => new Request(key).url));
296+
297+
const cache = await caches.open(name);
298+
const keys = (await cache.keys()).map(req => req.url).filter(url => !ignoredUrls.has(url));
299+
const entries = await Promise.all(keys.map(async key => ({
300+
key,
301+
value: !includeValues ? undefined : await (await cache.match(key))?.json(),
302+
})));
303+
304+
return entries;
305+
}
306+
307+
function printCacheEntries(name: string, entries: {key: string, value?: object}[]): void {
308+
const entriesStr = entries
309+
.map(({key, value}) => ` - ${key}${!value ? '' : `: ${JSON.stringify(value)}`}`)
310+
.join('\n');
311+
312+
console.log(`\nCache: ${name} (${entries.length} entries)\n${entriesStr}`);
313+
}
314+
}

goldens/size-tracking/aio-payloads.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"master": {
44
"uncompressed": {
55
"runtime-es2015": 3033,
6-
"main-es2015": 448690,
6+
"main-es2015": 450333,
77
"polyfills-es2015": 52343
88
}
99
}
@@ -12,7 +12,7 @@
1212
"master": {
1313
"uncompressed": {
1414
"runtime-es2015": 3033,
15-
"main-es2015": 448720,
15+
"main-es2015": 450363,
1616
"polyfills-es2015": 52493
1717
}
1818
}
@@ -21,7 +21,7 @@
2121
"master": {
2222
"uncompressed": {
2323
"runtime-es2015": 3153,
24-
"main-es2015": 433542,
24+
"main-es2015": 435185,
2525
"polyfills-es2015": 52493
2626
}
2727
}

0 commit comments

Comments
 (0)