diff --git a/aio/src/app/layout/doc-viewer/doc-viewer.component.ts b/aio/src/app/layout/doc-viewer/doc-viewer.component.ts index 5a5ed3f4d0..26c0528a84 100644 --- a/aio/src/app/layout/doc-viewer/doc-viewer.component.ts +++ b/aio/src/app/layout/doc-viewer/doc-viewer.component.ts @@ -143,10 +143,18 @@ export class DocViewerComponent implements OnDestroy { switchMap(() => this.swapViews(addTitleAndToc)), tap(() => this.docRendered.emit()), catchError(err => { - const errorMessage = (err instanceof Error) ? err.stack : err; + const errorMessage = `${(err instanceof Error) ? err.stack : err}`; this.logger.error(new Error(`[DocViewer] Error preparing document '${doc.id}': ${errorMessage}`)); this.nextViewContainer.innerHTML = ''; this.setNoIndex(true); + + // TODO(gkalpak): Remove this once gathering debug info is no longer needed. + if (/loading chunk \d+ failed/i.test(errorMessage)) { + // Print some info to help with debugging. + // (There is no reason to wait for this async call to complete before continuing.) + printSwDebugInfo(); + } + return this.void$; }), ); @@ -244,3 +252,63 @@ export class DocViewerComponent implements OnDestroy { ); } } + +// Helpers +/** + * Print some info regarding the ServiceWorker and the caches contents to help debugging potential + * issues with failing to find resources in the cache. + * (See https://github.com/angular/angular/issues/28114.) + */ +async function printSwDebugInfo(): Promise { + console.log(`\nServiceWorker: ${navigator.serviceWorker?.controller?.state ?? 'N/A'}`); + + if (typeof caches === 'undefined') { + console.log('\nCaches: N/A'); + } else { + const allCacheNames = await caches.keys(); + const swCacheNames = allCacheNames.filter(name => name.startsWith('ngsw:/:')); + + await findCachesAndPrintEntries(swCacheNames, 'db:control', true, ['manifests']); + await findCachesAndPrintEntries(swCacheNames, 'assets:app-shell:cache', false); + await findCachesAndPrintEntries(swCacheNames, 'assets:app-shell:meta', true); + } + + console.warn( + '\nIf 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.'); + + // Internal helpers + async function findCachesAndPrintEntries( + swCacheNames: string[], nameSuffix: string, includeValues: boolean, + ignoredKeys: string[] = []): Promise { + const cacheNames = swCacheNames.filter(name => name.endsWith(nameSuffix)); + + for (const cacheName of cacheNames) { + const cacheEntries = await getCacheEntries(cacheName, includeValues, ignoredKeys); + await printCacheEntries(cacheName, cacheEntries); + } + } + + async function getCacheEntries( + name: string, includeValues: boolean, + ignoredKeys: string[] = []): Promise<{key: string, value?: object}[]> { + const ignoredUrls = new Set(ignoredKeys.map(key => new Request(key).url)); + + const cache = await caches.open(name); + const keys = (await cache.keys()).map(req => req.url).filter(url => !ignoredUrls.has(url)); + const entries = await Promise.all(keys.map(async key => ({ + key, + value: !includeValues ? undefined : await (await cache.match(key))?.json(), + }))); + + return entries; + } + + function printCacheEntries(name: string, entries: {key: string, value?: object}[]): void { + const entriesStr = entries + .map(({key, value}) => ` - ${key}${!value ? '' : `: ${JSON.stringify(value)}`}`) + .join('\n'); + + console.log(`\nCache: ${name} (${entries.length} entries)\n${entriesStr}`); + } +} diff --git a/goldens/size-tracking/aio-payloads.json b/goldens/size-tracking/aio-payloads.json index fef0112d62..18cd9550d2 100755 --- a/goldens/size-tracking/aio-payloads.json +++ b/goldens/size-tracking/aio-payloads.json @@ -3,7 +3,7 @@ "master": { "uncompressed": { "runtime-es2015": 3033, - "main-es2015": 449310, + "main-es2015": 450953, "polyfills-es2015": 52343 } } @@ -12,7 +12,7 @@ "master": { "uncompressed": { "runtime-es2015": 3033, - "main-es2015": 449759, + "main-es2015": 451402, "polyfills-es2015": 52493 } } @@ -21,9 +21,9 @@ "master": { "uncompressed": { "runtime-es2015": 3153, - "main-es2015": 435362, + "main-es2015": 437005, "polyfills-es2015": 52493 } } } -} \ No newline at end of file +}