mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 04:38:33 +00:00
fix(producer): harden capture against timeouts, transient tab deaths, and OOM (#1842)
Four independent capture-infra hardening changes for the P2-5 failure bucket (~15K err / ~7K users): - protocolTimeout auto-scales by device-scaled output area (applied before probe launch, since it's immutable post ppt.launch()). - Single bounded transient retry (MAX_TRANSIENT_CAPTURE_RETRIES=1) on Target closed / Page crashed in the parallel disk-capture path; abort short-circuits before retry. - Narrow OOM classification (Set maximum size exceeded etc., disjoint from transient) → actionable guidance naming output dims. - StreamingEncoder.getExitError() threads FFmpeg's real exit reason into frame-0 encoder-death errors. Render-reliability workstream P2-5. Success measured on PostHog dashboard 1783183. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
180f368af1
commit
c0c3abf0f1
@@ -2006,3 +2006,35 @@ export function isTransientBrowserError(error: unknown): boolean {
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
return TRANSIENT_BROWSER_ERROR_PATTERNS.some((pattern) => pattern.test(message));
|
||||
}
|
||||
|
||||
// ── Memory-exhaustion classification ────────────────────────────────────────
|
||||
// A render can run the Node process (or a page-side allocation) out of memory
|
||||
// on an oversized composition — huge canvas, thousands of frames, or a very
|
||||
// large frame cache. These surface as cryptic V8 RangeErrors ("Set maximum
|
||||
// size exceeded", "Invalid array length"/"string length", "Array buffer
|
||||
// allocation failed") or a hard V8 heap-limit abort. They are NOT transient
|
||||
// (a retry re-hits the same ceiling) and NOT composition-logic bugs — they're
|
||||
// resource limits. Classify them so the caller can surface actionable guidance
|
||||
// (lower resolution / fps / duration, or enable low-memory mode) instead of a
|
||||
// raw RangeError.
|
||||
|
||||
// Deliberately specific: each pattern is a distinct V8/Node allocation-failure
|
||||
// signature. We intentionally do NOT match a bare /out of memory/ — that
|
||||
// substring appears in benign browser-console noise (WebGL `CONTEXT_LOST … out
|
||||
// of memory`, GPU driver notes) that gets carried into the error path, and
|
||||
// misclassifying it would replace the real failure message with generic OOM
|
||||
// guidance.
|
||||
const MEMORY_EXHAUSTION_ERROR_PATTERNS = [
|
||||
/Set maximum size exceeded/i,
|
||||
/Map maximum size exceeded/i,
|
||||
/Invalid (?:array|string) length/i,
|
||||
/Array buffer allocation failed/i,
|
||||
/Cannot create a string longer than/i,
|
||||
/Reached heap limit/i,
|
||||
/JavaScript heap out of memory/i,
|
||||
];
|
||||
|
||||
export function isMemoryExhaustionError(error: unknown): boolean {
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
return MEMORY_EXHAUSTION_ERROR_PATTERNS.some((pattern) => pattern.test(message));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user