From efd7db1b6c4b9a24f20d683dd2b2853d83f16a21 Mon Sep 17 00:00:00 2001 From: Peter Hedenskog Date: Sun, 24 May 2026 08:19:43 +0200 Subject: [PATCH] har: skip pages with no matching entries instead of throwing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Occasionally a HAR contains a page object whose pageref has no matching entries — typically a navigation that didn't produce any requests, or an extension-injected page. Three places in lib/support/har/index.js treated this shape as impossible: getDocumentRequests dereferenced the result of shift() without a guard, getFinalURL dereferenced the result of pop() without a guard, and getMainDocumentTimings wrapped its entire per-page loop in a single try/catch so one bad page wiped out the main-document timings for every other page in the same HAR. The downstream consequence was a noisy and confusing log triplet: a "page without an URL in the HAR" warning, a "Could not get main document timings TypeError: Cannot read properties of undefined (reading 'response')" error, and then in sitespeed.io a coach-data error because the timings array was empty. Guard the three known crash points and continue past pages that can't be resolved. The existing top-level try/catch in getMainDocumentTimings stays as a safety net; the existing unit tests still pass. Co-authored-by: Claude noreply@anthropic.com Change-Id: I5c6f2d7445bfdf1159c883f7dfc8f70d10bd3b32 --- lib/support/har/index.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/support/har/index.js b/lib/support/har/index.js index 9cfdc1d6f..cd1cba97a 100644 --- a/lib/support/har/index.js +++ b/lib/support/har/index.js @@ -42,6 +42,7 @@ function getDocumentRequests(entries, pageId) { do { entry = pageEntries.shift(); + if (!entry) break; requests.push(entry); } while (entry.response.redirectURL); @@ -52,7 +53,7 @@ function getFinalURL(entries, pageref) { const requests = getDocumentRequests(entries, pageref); const finalEntry = requests.pop(); - return finalEntry.request.url; + return finalEntry ? finalEntry.request.url : undefined; } function addExtrasToHAR( @@ -249,13 +250,16 @@ export function getMainDocumentTimings(har) { for (let page of har.log.pages) { const pageId = page.id; const url = page._url; + if (url === undefined) continue; let pageEntries = [...entries]; const finalURL = getFinalURL(pageEntries, pageId); + if (finalURL === undefined) continue; pageEntries = pageEntries.filter( entry => entry.pageref === pageId && entry.request.url === finalURL ); + if (pageEntries.length === 0) continue; timings.push({ url, timings: pageEntries[0].timings }); }