mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 04:38:33 +00:00
fix(engine): retry probe on pollHfReady zero-duration timeout (#1824)
Renders were failing outright with "[FrameCapture] Composition has zero duration. Runtime ready: false, ..." whenever window.__renderReady didn't flip true within playerReadyTimeout (45s) — most often under host contention (e.g. several renders running concurrently), never from a defect in the composition itself. Confirmed by re-running an affected composition standalone: it succeeded immediately (initMs ~3.5-4.4s vs. the 45s timeout it hit under concurrent load). The probe stage already retries once with a fresh browser session for exactly this class of "succeeds on retry" infra flakiness (frame detachment, disconnects, navigation timeouts, launch failures), but isTransientBrowserError didn't recognize this message, so it fell through to an immediate, unretried failure. Match "Composition has zero duration ... Runtime ready: false" as transient. Left the "Runtime ready: true" case (pollHfReady's fast-fail: no GSAP timeline and no data-duration) unmatched — that's a genuine authoring bug, not a timing fluke, and should keep failing fast.
This commit is contained in:
@@ -15,6 +15,10 @@ describe("isTransientBrowserError", () => {
|
||||
"Failed to launch the browser process! TROUBLESHOOTING: https://pptr.dev/troubleshooting",
|
||||
"connect ECONNREFUSED 127.0.0.1:9222",
|
||||
"Navigation timeout of 60000 ms exceeded",
|
||||
// pollHfReady timed out before window.__renderReady flipped true — the
|
||||
// classic symptom of a slow/contended host (e.g. several renders running
|
||||
// concurrently); a fresh browser session on retry usually clears it.
|
||||
"[FrameCapture] Composition has zero duration.\n Runtime ready: false, __player: true, __hf.seek: true, GSAP timeline: true, data-duration: 53.3s",
|
||||
])("returns true for transient error: %s", (message) => {
|
||||
expect(isTransientBrowserError(new Error(message))).toBe(true);
|
||||
});
|
||||
@@ -25,6 +29,10 @@ describe("isTransientBrowserError", () => {
|
||||
"Composition duration is 0",
|
||||
"SYSTEM_FONT_USED: -apple-system",
|
||||
"",
|
||||
// The runtime finished initializing (renderReady: true) and still reports
|
||||
// zero duration — a genuine authoring bug (no timeline, no data-duration),
|
||||
// not a transient host hiccup. Must keep fast-failing without a retry.
|
||||
"[FrameCapture] Composition has zero duration.\n Runtime ready: true, __player: true, __hf.seek: true, GSAP timeline: false, data-duration: not set",
|
||||
])("returns false for non-transient error: %s", (message) => {
|
||||
expect(isTransientBrowserError(new Error(message))).toBe(false);
|
||||
});
|
||||
|
||||
@@ -1975,6 +1975,14 @@ const TRANSIENT_BROWSER_ERROR_PATTERNS = [
|
||||
/Failed to launch the browser process/i,
|
||||
/Navigation timeout of \d+ ms exceeded/i,
|
||||
/ECONNREFUSED/i,
|
||||
// pollHfReady's own timeout — thrown when window.__renderReady never flips
|
||||
// true within playerReadyTimeout. "Runtime ready: false" means init simply
|
||||
// didn't finish in time (commonly a slow/contended host, e.g. several
|
||||
// concurrent renders), which a fresh session usually clears on retry. This
|
||||
// is distinct from the "Runtime ready: true" fast-fail case a few lines up
|
||||
// in pollHfReady (no timeline + no data-duration) — that's a genuine
|
||||
// authoring bug and intentionally NOT matched here, so it still fails fast.
|
||||
/Composition has zero duration[\s\S]*Runtime ready: false/,
|
||||
];
|
||||
|
||||
export function isTransientBrowserError(error: unknown): boolean {
|
||||
|
||||
Reference in New Issue
Block a user