fix(producer): retry probe navigation timeouts (#1713)

This commit is contained in:
Miguel Ángel
2026-06-25 10:52:38 -04:00
committed by GitHub
parent 64eaad7d69
commit 0558b8761e
3 changed files with 20 additions and 2 deletions
@@ -14,13 +14,13 @@ describe("isTransientBrowserError", () => {
"Cannot find context with specified id",
"Failed to launch the browser process! TROUBLESHOOTING: https://pptr.dev/troubleshooting",
"connect ECONNREFUSED 127.0.0.1:9222",
"Navigation timeout of 60000 ms exceeded",
])("returns true for transient error: %s", (message) => {
expect(isTransientBrowserError(new Error(message))).toBe(true);
});
it.each([
"net::ERR_NAME_NOT_RESOLVED",
"TimeoutError: Navigation timeout of 30000 ms exceeded",
"FONT_FETCH_FAILED: Inter",
"Composition duration is 0",
"SYSTEM_FONT_USED: -apple-system",
@@ -1961,6 +1961,7 @@ const TRANSIENT_BROWSER_ERROR_PATTERNS = [
/Execution context was destroyed/i,
/Cannot find context with specified id/i,
/Failed to launch the browser process/i,
/Navigation timeout of \d+ ms exceeded/i,
/ECONNREFUSED/i,
];
@@ -69,7 +69,7 @@ mock.module("@hyperframes/engine", () => ({
// live in frameCapture-transientErrors.test.ts — update both if patterns change.
isTransientBrowserError: (error: unknown) => {
const msg = error instanceof Error ? error.message : String(error);
return /Navigating frame was detached|Target closed|Session closed|browser has disconnected|Page crashed|Execution context was destroyed|Cannot find context with specified id|Failed to launch the browser process|ECONNREFUSED/i.test(
return /Navigating frame was detached|Target closed|Session closed|browser has disconnected|Page crashed|Execution context was destroyed|Cannot find context with specified id|Failed to launch the browser process|Navigation timeout of \d+ ms exceeded|ECONNREFUSED/i.test(
msg,
);
},
@@ -276,6 +276,23 @@ describe("runProbeStage — transient browser error retry (#1687)", () => {
expect(result.probeSession).not.toBeNull();
});
it("retries once on a browser-probe navigation timeout and succeeds", async () => {
resetRetryMocks();
capturedCfgs.length = 0;
initializeSessionError = new Error("Navigation timeout of 60000 ms exceeded");
initializeSessionFailUntilAttempt = 1;
const { runProbeStage } = await import("./probeStage.js");
const input = makeProbeInput({ cfgForceScreenshot: false, stageForceScreenshot: false });
const result = await runProbeStage(input);
expect(initializeSessionCallCount).toBe(2);
expect(closeCaptureSessionCallCount).toBe(1);
expect(result.duration).toBe(5);
expect(result.probeSession).not.toBeNull();
});
it("throws immediately on a non-transient error without retrying", async () => {
resetRetryMocks();
capturedCfgs.length = 0;