mirror of
https://github.com/nexu-io/open-design.git
synced 2026-07-06 22:31:53 +08:00
* fix(analytics): stamp frame platform + drop fetch-failure noise in exception transport The hand-rolled browser-exception transport in error-tracking.ts (the sole $exception source since client.ts sets capture_exceptions:false) had two bugs that PostHog's weekly digest surfaced as "512K exceptions / 511K failed to ingest": 1. Frames never carried `platform`. PostHog's exception ingestion requires it per frame to pick the symbolication/grouping strategy; without it every event failed processing with "missing field platform" and was dropped server-side. 100% of our ingested $exception events had platform=(missing), all from capture_source=web/error-tracking. Now stamped 'web:javascript' on every frame, matching posthog-js. 2. `TypeError: Failed to fetch` from the packaged app's daemon connection dropping (restart, boot race, navigation/unmount abort, offline) was ~90% of all captured exceptions — environmental noise, not bugs, one polling loop can emit thousands. Dropped at the capture chokepoint along with AbortError and the WebKit/Firefox network-error wordings. Also hardens the telemetry beacon: `void fetch(...)` had only a synchronous try/catch, so a failed beacon rejected unhandled and got re-captured as its own Failed to fetch — a self-amplifying loop. Now `.catch()`-ed. Red specs in error-tracking.test.ts go red on main (frames lack platform; noise is dispatched) and green here. * fix(analytics): scope fetch-noise drop to packaged runtime, stop dropping AbortError Address review: captureException is the single chokepoint for window.error / unhandledrejection / reportHandledException, so a blanket drop of `Failed to fetch` would also suppress a real broken-/api/* or CORS/TLS signal from the normal web app — and blanket-dropping AbortError was never justified by the data. - Gate the fetch-failure drop on the exception originating in packaged app code (od:// stack origin), which is where the ~90% daemon-connection churn lives. The same TypeError from a web (http/https) context stays captured. - Remove the AbortError drop entirely (not a measured noise source, and not necessarily fetch-lifecycle cancellation). Test now asserts the invariant directly: packaged od:// fetch noise dropped, the identical web-origin error kept, AbortError kept. * test(analytics): cover beacon-failure self-amplification backstop Address review: add a regression that a failed telemetry beacon, surfacing as an unhandledrejection from od:// transport code, does not re-enter capture as a second $exception/beacon. Exercises the packaged-noise backstop (the loop-breaking layer observable under jsdom; dispatch()'s .catch() is a process-level promise rejection that jsdom does not route to window.onunhandledrejection, so it is not unit-observable here). * fix(analytics): recognize file:// app-bundle frames as packaged origin Address blocking review: packaged exceptions don't only arrive as od:// frames — source-mapped frames surface as file:///.../<Channel>.app/Contents/Resources/... (the shape scrub.ts rewrites). The od://-only check let those packaged fetch-failures leak through. Broaden originatesInPackagedApp to also match the .app/Contents/Resources bundle marker (channel-agnostic, so Beta/Preview builds are covered). Regression added: file:// app-bundle Failed-to-fetch stacks are dropped too; red against the od://-only check, green here.