mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-07 01:56:04 +00:00
After hf#641 inlined the runtime IIFE into every bundle, lint tools
inspecting bundled output (including Abhay's c2v eval) started flagging
empty `catch {}` blocks across the runtime. The source had explanatory
comments inside, but esbuild's minifier strips them — the IIFE ships
~10 visible patterns of `}catch{}` and consumers' linters fire on each.
Each empty catch is intentional best-effort error swallowing —
postMessage to a parent frame that may not exist, `media.play()` /
`pause()` that throw under autoplay restrictions, timeline `seek()` on
a disposed timeline, anime.js / lottie feature detection on hosts that
don't load those libraries, etc. The right behaviour stays "tried,
didn't work, move on", but doing it visibly improves three things:
- lint clean: helper call is a real statement; no `no-empty` warnings
survive minification
- debuggable: flip `window.__hfDebug = true` in DevTools to see every
swallow site with `console.debug` (silent in prod by default)
- observable: studio / embeddings can install
`window.__hf.onSwallowed = handler` to collect runtime swallow
events without polluting the page console
Implementation: `packages/core/src/runtime/diagnostics.ts` exports
`swallow(label, err?)`. 41 catch sites across 12 runtime files
converted via mechanical pass (auto-generated `runtime.<module>.siteN`
labels — labels can be tightened site-by-site as a follow-up; the
shape of the change is what matters here).
Verification:
- core 674/674 (incl. 6 new diagnostics tests covering silent default,
__hfDebug logging, legacy __HYPERFRAMES_DEBUG flag, handler hook,
handler-throws-doesn't-recurse, both-active)
- typecheck clean
- format / lint clean
- runtime IIFE rebuilds successfully (`bun run build:hyperframes-runtime`)
Refs Abhay's c2v eval — bundler artefacts now lint-clean with the
runtime body inlined.
78 lines
2.2 KiB
TypeScript
78 lines
2.2 KiB
TypeScript
// @vitest-environment happy-dom
|
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
import { swallow } from "./diagnostics";
|
|
|
|
interface HFTestWindow {
|
|
__hfDebug?: boolean;
|
|
__HYPERFRAMES_DEBUG?: boolean;
|
|
__hf?: {
|
|
onSwallowed?: (e: { label: string; error: unknown }) => void;
|
|
};
|
|
}
|
|
|
|
describe("swallow", () => {
|
|
const w = window as unknown as HFTestWindow;
|
|
const originalDebug = console.debug;
|
|
|
|
beforeEach(() => {
|
|
delete w.__hfDebug;
|
|
delete w.__HYPERFRAMES_DEBUG;
|
|
delete w.__hf;
|
|
console.debug = vi.fn();
|
|
});
|
|
|
|
afterEach(() => {
|
|
console.debug = originalDebug;
|
|
delete w.__hfDebug;
|
|
delete w.__HYPERFRAMES_DEBUG;
|
|
delete w.__hf;
|
|
});
|
|
|
|
it("is silent by default — no console output, no handler call", () => {
|
|
swallow("test.silent", new Error("boom"));
|
|
expect(console.debug).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it("logs to console.debug when window.__hfDebug is true", () => {
|
|
w.__hfDebug = true;
|
|
const err = new Error("boom");
|
|
swallow("test.debug", err);
|
|
expect(console.debug).toHaveBeenCalledWith("[hyperframes] test.debug swallowed:", err);
|
|
});
|
|
|
|
it("also honors window.__HYPERFRAMES_DEBUG (legacy flag)", () => {
|
|
w.__HYPERFRAMES_DEBUG = true;
|
|
swallow("test.legacy", "string-error");
|
|
expect(console.debug).toHaveBeenCalledWith(
|
|
"[hyperframes] test.legacy swallowed:",
|
|
"string-error",
|
|
);
|
|
});
|
|
|
|
it("dispatches to window.__hf.onSwallowed when installed", () => {
|
|
const handler = vi.fn();
|
|
w.__hf = { onSwallowed: handler };
|
|
const err = new Error("from handler");
|
|
swallow("test.handler", err);
|
|
expect(handler).toHaveBeenCalledWith({ label: "test.handler", error: err });
|
|
});
|
|
|
|
it("does not propagate errors from the user-installed handler", () => {
|
|
w.__hf = {
|
|
onSwallowed: () => {
|
|
throw new Error("handler exploded");
|
|
},
|
|
};
|
|
expect(() => swallow("test.handler-throws", new Error("real"))).not.toThrow();
|
|
});
|
|
|
|
it("can run with both handler AND debug flag set", () => {
|
|
w.__hfDebug = true;
|
|
const handler = vi.fn();
|
|
w.__hf = { onSwallowed: handler };
|
|
swallow("test.both", "err");
|
|
expect(handler).toHaveBeenCalled();
|
|
expect(console.debug).toHaveBeenCalled();
|
|
});
|
|
});
|