feat: report assertion failures to Datadog RUM on cloud builds - #14254
feat: report assertion failures to Datadog RUM on cloud builds#14254mattmillerai wants to merge 2 commits into
Conversation
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 46 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (6)
Comment |
📄 Knowledge reviewDosu skipped reviewing this PR because your organization has used its |
🎨 Storybook: ✅ Built — View Storybook🎭 Playwright: ✅ 1759 passed, 0 failed📊 Browser Reports
📦 Bundle: 8.14 MB gzip 🔴 +213 BDetailsSummary
Category Glance App Entry Points — 3.63 kB (baseline 3.63 kB) • ⚪ 0 BMain entry bundles and manifests
Status: 1 added / 1 removed Graph Workspace — 1.28 MB (baseline 1.28 MB) • ⚪ 0 BGraph editor runtime, canvas, workflow orchestration
Status: 1 added / 1 removed / 1 unchanged Views & Navigation — 112 kB (baseline 112 kB) • ⚪ 0 BTop-level views, pages, and routed surfaces
Status: 12 added / 12 removed / 4 unchanged Panels & Settings — 551 kB (baseline 551 kB) • ⚪ 0 BConfiguration panels, inspectors, and settings screens
Status: 11 added / 11 removed / 15 unchanged User & Accounts — 29.1 kB (baseline 29.1 kB) • ⚪ 0 BAuthentication, profile, and account management bundles
Status: 7 added / 7 removed / 3 unchanged Editors & Dialogs — 121 kB (baseline 121 kB) • ⚪ 0 BModals, dialogs, drawers, and in-app editors
Status: 5 added / 5 removed / 1 unchanged UI Components — 64.8 kB (baseline 64.8 kB) • ⚪ 0 BReusable component library chunks
Status: 6 added / 6 removed / 8 unchanged Data & Services — 3.42 MB (baseline 3.42 MB) • 🔴 +314 BStores, services, APIs, and repositories
Status: 14 added / 14 removed / 3 unchanged Utilities & Hooks — 369 kB (baseline 369 kB) • ⚪ 0 BHelpers, composables, and utility bundles
Status: 15 added / 15 removed / 20 unchanged Vendor & Third-Party — 15.7 MB (baseline 15.7 MB) • ⚪ 0 BExternal libraries and shared vendor chunks Status: 16 unchanged Other — 12.5 MB (baseline 12.5 MB) • ⚪ 0 BBundles that do not match a named category
Status: 68 added / 68 removed / 207 unchanged ⚡ Performance Report
Show regressions
All metrics
Historical variance (last 15 runs)
Trend (last 15 commits on main)
Raw data{
"timestamp": "2026-07-29T09:56:18.271Z",
"gitSha": "8bad187d17e8d22ff88d999a5e9b445dca6b2776",
"branch": "matt/be-5046-assert-rum-reporter",
"measurements": [
{
"name": "canvas-idle",
"durationMs": 2054.4009999999844,
"styleRecalcs": 9,
"styleRecalcDurationMs": 10.007,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 529.809,
"heapDeltaBytes": 3723340,
"heapUsedBytes": 71624252,
"domNodes": 18,
"jsHeapTotalBytes": 20316160,
"scriptDurationMs": 23.343999999999998,
"eventListeners": 4,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "canvas-idle",
"durationMs": 2038.520999999946,
"styleRecalcs": 10,
"styleRecalcDurationMs": 10.33,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 501.2340000000001,
"heapDeltaBytes": 3652560,
"heapUsedBytes": 71552736,
"domNodes": 20,
"jsHeapTotalBytes": 20316160,
"scriptDurationMs": 22.21,
"eventListeners": 4,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "canvas-mouse-sweep",
"durationMs": 2103.6920000000237,
"styleRecalcs": 77,
"styleRecalcDurationMs": 45.962,
"layouts": 12,
"layoutDurationMs": 3.842,
"taskDurationMs": 1109.192,
"heapDeltaBytes": -16028460,
"heapUsedBytes": 51794236,
"domNodes": -276,
"jsHeapTotalBytes": 20967424,
"scriptDurationMs": 145.581,
"eventListeners": -148,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "canvas-mouse-sweep",
"durationMs": 1846.8329999999469,
"styleRecalcs": 73,
"styleRecalcDurationMs": 38.802,
"layouts": 12,
"layoutDurationMs": 3.326,
"taskDurationMs": 928.0110000000001,
"heapDeltaBytes": -14183400,
"heapUsedBytes": 53753228,
"domNodes": -273,
"jsHeapTotalBytes": 21491712,
"scriptDurationMs": 127.754,
"eventListeners": -148,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333335,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "canvas-zoom-sweep",
"durationMs": 1740.0470000000041,
"styleRecalcs": 32,
"styleRecalcDurationMs": 18.767,
"layouts": 6,
"layoutDurationMs": 0.5530000000000002,
"taskDurationMs": 405.675,
"heapDeltaBytes": 7214184,
"heapUsedBytes": 75204244,
"domNodes": 78,
"jsHeapTotalBytes": 20054016,
"scriptDurationMs": 21.776999999999997,
"eventListeners": 19,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "canvas-zoom-sweep",
"durationMs": 1754.9679999999626,
"styleRecalcs": 31,
"styleRecalcDurationMs": 17.931,
"layouts": 6,
"layoutDurationMs": 0.687,
"taskDurationMs": 398.025,
"heapDeltaBytes": 7163980,
"heapUsedBytes": 75305228,
"domNodes": 78,
"jsHeapTotalBytes": 20578304,
"scriptDurationMs": 22.294,
"eventListeners": 19,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.699999999999818
},
{
"name": "dom-widget-clipping",
"durationMs": 641.8570000000159,
"styleRecalcs": 11,
"styleRecalcDurationMs": 8.068000000000001,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 407.484,
"heapDeltaBytes": -12264516,
"heapUsedBytes": 55614960,
"domNodes": 18,
"jsHeapTotalBytes": 21364736,
"scriptDurationMs": 68.59499999999998,
"eventListeners": 2,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "dom-widget-clipping",
"durationMs": 588.7189999999691,
"styleRecalcs": 10,
"styleRecalcDurationMs": 7.077999999999999,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 375.21099999999996,
"heapDeltaBytes": -12500048,
"heapUsedBytes": 55649152,
"domNodes": 16,
"jsHeapTotalBytes": 21889024,
"scriptDurationMs": 60.172000000000004,
"eventListeners": 2,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "large-graph-idle",
"durationMs": 2042.6089999999704,
"styleRecalcs": 8,
"styleRecalcDurationMs": 8.118,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 743.136,
"heapDeltaBytes": 6616692,
"heapUsedBytes": 65609716,
"domNodes": -275,
"jsHeapTotalBytes": 4784128,
"scriptDurationMs": 123.31800000000001,
"eventListeners": -144,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "large-graph-idle",
"durationMs": 2026.9049999999424,
"styleRecalcs": 7,
"styleRecalcDurationMs": 6.670000000000003,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 726.2600000000001,
"heapDeltaBytes": 6871392,
"heapUsedBytes": 68157428,
"domNodes": -273,
"jsHeapTotalBytes": 4521984,
"scriptDurationMs": 118.48400000000001,
"eventListeners": -142,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "large-graph-pan",
"durationMs": 2251.6769999999724,
"styleRecalcs": 68,
"styleRecalcDurationMs": 14.415000000000001,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 1375.694,
"heapDeltaBytes": 4517704,
"heapUsedBytes": 64197292,
"domNodes": -277,
"jsHeapTotalBytes": 4464640,
"scriptDurationMs": 455.414,
"eventListeners": -142,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "large-graph-pan",
"durationMs": 2255.941000000007,
"styleRecalcs": 69,
"styleRecalcDurationMs": 15.027000000000003,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 1394.148,
"heapDeltaBytes": 2276944,
"heapUsedBytes": 62410328,
"domNodes": -278,
"jsHeapTotalBytes": 5251072,
"scriptDurationMs": 484.60800000000006,
"eventListeners": -144,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "large-graph-zoom",
"durationMs": 3361.383999999987,
"styleRecalcs": 65,
"styleRecalcDurationMs": 15.200000000000001,
"layouts": 60,
"layoutDurationMs": 7.494000000000001,
"taskDurationMs": 1647.6589999999999,
"heapDeltaBytes": 6658072,
"heapUsedBytes": 68112196,
"domNodes": -280,
"jsHeapTotalBytes": 8978432,
"scriptDurationMs": 567.561,
"eventListeners": -148,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "large-graph-zoom",
"durationMs": 3296.3479999999663,
"styleRecalcs": 64,
"styleRecalcDurationMs": 14.719,
"layouts": 60,
"layoutDurationMs": 7.476999999999999,
"taskDurationMs": 1598.5149999999999,
"heapDeltaBytes": 2959916,
"heapUsedBytes": 65155036,
"domNodes": -280,
"jsHeapTotalBytes": 7667712,
"scriptDurationMs": 555.4,
"eventListeners": -148,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.699999999999818
},
{
"name": "minimap-idle",
"durationMs": 2030.149999999992,
"styleRecalcs": 8,
"styleRecalcDurationMs": 9.153999999999998,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 760.086,
"heapDeltaBytes": 6418960,
"heapUsedBytes": 66836592,
"domNodes": -279,
"jsHeapTotalBytes": 3997696,
"scriptDurationMs": 123.43799999999999,
"eventListeners": -146,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "minimap-idle",
"durationMs": 2074.8559999999543,
"styleRecalcs": 8,
"styleRecalcDurationMs": 10.421,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 757.5450000000001,
"heapDeltaBytes": 7439576,
"heapUsedBytes": 68171124,
"domNodes": -277,
"jsHeapTotalBytes": 4784128,
"scriptDurationMs": 127.51200000000001,
"eventListeners": -144,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333335,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "subgraph-dom-widget-clipping",
"durationMs": 620.4809999999839,
"styleRecalcs": 48,
"styleRecalcDurationMs": 11.986,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 413.213,
"heapDeltaBytes": -11501296,
"heapUsedBytes": 56539460,
"domNodes": 22,
"jsHeapTotalBytes": 21889024,
"scriptDurationMs": 119.348,
"eventListeners": 8,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333335,
"p95FrameDurationMs": 16.699999999999818
},
{
"name": "subgraph-dom-widget-clipping",
"durationMs": 630.1220000000285,
"styleRecalcs": 47,
"styleRecalcDurationMs": 11.118999999999998,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 417.067,
"heapDeltaBytes": -12115060,
"heapUsedBytes": 55866996,
"domNodes": 20,
"jsHeapTotalBytes": 22151168,
"scriptDurationMs": 121.362,
"eventListeners": 8,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "subgraph-idle",
"durationMs": 2007.758000000024,
"styleRecalcs": 10,
"styleRecalcDurationMs": 10.39,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 502.333,
"heapDeltaBytes": 3517336,
"heapUsedBytes": 71400540,
"domNodes": 20,
"jsHeapTotalBytes": 20840448,
"scriptDurationMs": 18.759999999999998,
"eventListeners": 4,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66999999999998,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "subgraph-idle",
"durationMs": 2001.846999999998,
"styleRecalcs": 9,
"styleRecalcDurationMs": 8.402999999999999,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 490.84200000000004,
"heapDeltaBytes": 3419588,
"heapUsedBytes": 71491768,
"domNodes": 18,
"jsHeapTotalBytes": 20840448,
"scriptDurationMs": 16.746000000000002,
"eventListeners": 4,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333335,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "subgraph-mouse-sweep",
"durationMs": 1733.9999999999804,
"styleRecalcs": 75,
"styleRecalcDurationMs": 40.063,
"layouts": 16,
"layoutDurationMs": 4.412,
"taskDurationMs": 876.976,
"heapDeltaBytes": -21103188,
"heapUsedBytes": 47041220,
"domNodes": -276,
"jsHeapTotalBytes": 20967424,
"scriptDurationMs": 102.32999999999998,
"eventListeners": -148,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66999999999998,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "subgraph-mouse-sweep",
"durationMs": 1741.5070000000696,
"styleRecalcs": 76,
"styleRecalcDurationMs": 40.37299999999999,
"layouts": 16,
"layoutDurationMs": 4.547,
"taskDurationMs": 854.8260000000001,
"heapDeltaBytes": -20920208,
"heapUsedBytes": 47358244,
"domNodes": -275,
"jsHeapTotalBytes": 20967424,
"scriptDurationMs": 100.37,
"eventListeners": -148,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "subgraph-transition-enter",
"durationMs": 1436.095000000023,
"styleRecalcs": 18,
"styleRecalcDurationMs": 32.367999999999995,
"layouts": 14,
"layoutDurationMs": 13.269000000000004,
"taskDurationMs": 1021.5970000000001,
"heapDeltaBytes": 31052712,
"heapUsedBytes": 99420352,
"domNodes": 13673,
"jsHeapTotalBytes": 14942208,
"scriptDurationMs": 39.23299999999999,
"eventListeners": 2371,
"totalBlockingTimeMs": 139,
"frameDurationMs": 16.666666666666696,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "viewport-pan-sweep",
"durationMs": 8399.347999999974,
"styleRecalcs": 249,
"styleRecalcDurationMs": 37.748999999999995,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 4769.862,
"heapDeltaBytes": 9840444,
"heapUsedBytes": 69538392,
"domNodes": -276,
"jsHeapTotalBytes": 7319552,
"scriptDurationMs": 1444.326,
"eventListeners": -126,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "viewport-pan-sweep",
"durationMs": 8378.544000000034,
"styleRecalcs": 249,
"styleRecalcDurationMs": 36.693000000000005,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 4662.714,
"heapDeltaBytes": 10254468,
"heapUsedBytes": 69645752,
"domNodes": -275,
"jsHeapTotalBytes": 6795264,
"scriptDurationMs": 1421.1589999999999,
"eventListeners": -126,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "vue-large-graph-idle",
"durationMs": 17494.242999999984,
"styleRecalcs": 0,
"styleRecalcDurationMs": 0,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 17474.607000000004,
"heapDeltaBytes": -43797364,
"heapUsedBytes": 165753768,
"domNodes": -8312,
"jsHeapTotalBytes": -15405056,
"scriptDurationMs": 592.801,
"eventListeners": -16385,
"totalBlockingTimeMs": 0,
"frameDurationMs": 17.776666666666642,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "vue-large-graph-idle",
"durationMs": 17317.69200000008,
"styleRecalcs": 0,
"styleRecalcDurationMs": 0,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 17292.73,
"heapDeltaBytes": -28141324,
"heapUsedBytes": 176818972,
"domNodes": -8312,
"jsHeapTotalBytes": -14880768,
"scriptDurationMs": 585.0379999999999,
"eventListeners": -16389,
"totalBlockingTimeMs": 0,
"frameDurationMs": 17.776666666666642,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "vue-large-graph-pan",
"durationMs": 21261.398999999983,
"styleRecalcs": 149,
"styleRecalcDurationMs": 19.994999999999983,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 21192.696,
"heapDeltaBytes": -52598944,
"heapUsedBytes": 155886232,
"domNodes": -8312,
"jsHeapTotalBytes": -14356480,
"scriptDurationMs": 932.0079999999999,
"eventListeners": -16383,
"totalBlockingTimeMs": 293,
"frameDurationMs": 17.776666666666642,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "vue-large-graph-pan",
"durationMs": 21009.824000000095,
"styleRecalcs": 143,
"styleRecalcDurationMs": 18.00400000000002,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 20938.137000000002,
"heapDeltaBytes": -21561200,
"heapUsedBytes": 178955500,
"domNodes": -8312,
"jsHeapTotalBytes": -14962688,
"scriptDurationMs": 893.2719999999998,
"eventListeners": -16383,
"totalBlockingTimeMs": 169,
"frameDurationMs": 17.773333333333238,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "workflow-execution",
"durationMs": 115.51199999996697,
"styleRecalcs": 9,
"styleRecalcDurationMs": 17.173000000000002,
"layouts": 3,
"layoutDurationMs": 1.449,
"taskDurationMs": 87.62899999999999,
"heapDeltaBytes": 3099704,
"heapUsedBytes": 70169600,
"domNodes": 134,
"jsHeapTotalBytes": 3407872,
"scriptDurationMs": 8.929000000000002,
"eventListeners": 17,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "workflow-execution",
"durationMs": 455.7320000000118,
"styleRecalcs": 13,
"styleRecalcDurationMs": 17.777,
"layouts": 2,
"layoutDurationMs": 0.30600000000000005,
"taskDurationMs": 105.033,
"heapDeltaBytes": -16300212,
"heapUsedBytes": 50650124,
"domNodes": 119,
"jsHeapTotalBytes": 7733248,
"scriptDurationMs": 9.262,
"eventListeners": 65,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.699999999999818
}
]
} |
There was a problem hiding this comment.
🔍 Cursor Review — Consolidated panel
Triggered by @mattmillerai.
Found 3 finding(s).
| Severity | Count |
|---|---|
| 🟡 Medium | 2 |
| 🟢 Low | 1 |
Panel: 8/8 reviewers contributed findings.
Codecov Report❌ Patch coverage is
@@ Coverage Diff @@
## main #14254 +/- ##
==========================================
- Coverage 80.11% 79.69% -0.42%
==========================================
Files 1755 1755
Lines 112815 110319 -2496
Branches 38321 36836 -1485
==========================================
- Hits 90382 87923 -2459
+ Misses 21915 21876 -39
- Partials 518 520 +2
Flags with carried forward coverage won't be shown. Click here to find out more.
... and 34 files with indirect coverage changes 🚀 New features to boost your workflow:
|
Assert messages are now shipped to Datadog RUM on cloud builds. The only production assert caller interpolated the workflow path into its message, so every reported failure carried user content to an external vendor. Move the path into the local dedup key only and document the constraint on assert() itself. Also release the message and the cached SDK import when a send fails: the rejected import promise was cached forever and the message had already consumed a cap slot, so one transient failure permanently disabled reporting for the session.
|
Superseding this with #15189 — flagging the details since it renames a file this branch owns. Context: #15063 review raised that What carried over unchanged:
What changed:
The Closing this as superseded, but happy to reopen if you'd rather land the reporter your way and have #15189 rebase onto it instead. |
ELI-5
When the app catches itself in an impossible state it calls
assert(). Today that failure gets shouted into the browser console and nowhere else on cloud production, so nobody ever hears it. This wires those failures into Datadog Error Tracking for cloud builds — with a mute button so a broken render loop can't flood the pipe.Summary
Assertion failures are invisible on cloud production: the only assert reporter (
src/main.ts) reports to Sentry whenisDesktopand toasts whenisNightly, and both are false on cloud, leaving invariant failures console-only. This adds anisCloudbranch that forwards them to Datadog RUM Error Tracking, which is already initialised for cloud insrc/bootstrap.ts.Changes
src/platform/telemetry/assertRumReporter.ts—reportAssertFailureToRum(message)sendsdatadogRum.addError(new Error(message), { source: 'invariant-assert' }), deduplicated by exact message and capped at 20 reports per session.src/main.tscalls it from a newisCloudbranch inside the existingsetAssertReportercallback; the desktop and nightly branches are untouched, andsrc/base/assert.ts(contract and console behaviour) is unchanged.@datadog/browser-rumis already a dependency and is loaded on cloud bybootstrap.tsbeforemain.tsruns, so the lazyimport()resolves from the module cache.Review Focus
addErrorrather thanaddAction: errors land in Error Tracking with stack traces and message-based grouping, which is what makes them monitorable/alertable. The existingrumBeforeSendfilter passes them through — its drop rules only matchintervention:,ResizeObserver loop, and network noise from a host allowlist — and it auto-tagserror.origin: first_partyfrom the/assets/stack frames.The
Erroris constructed synchronously in the reporter, before the dynamicimport()is awaited, so its stack captures the realassert()call site (assert()invokes the reporter synchronously). There is a unit test that fails if this construction moves into the.thencallback — verified by mutating the source.Two judgment calls worth a look:
rumModule ??= import('@datadog/browser-rum')) instead of callingimport()per report. On cloud this is behaviourally identical — the module registry already caches the module — but it means a rejected import is cached too, so a one-off chunk-load failure would silently disable assert reporting for the rest of the session rather than retrying on the next assert. Givenbootstrap.tshas already resolved the SDK on cloud, that failure path is close to unreachable, and dropping telemetry beats retrying a broken import up to 20 times. It also matters for testability: Vitest 4's mocker re-runs thevi.mockfactory on each dynamic import, so without the cache the second and subsequent reports land on throwaway mock instances and the dedupe/cap behaviour can't be observed.Setdoubles as the cap counter — every reported message is added to it, soreportedMessages.sizeis the report count. One piece of state, no separate counter to keep in sync.Bundle impact:
main.tsgains a static import of the ~30-line reporter module, not of the RUM SDK. The SDK reference is an erasedimport typeplus a lazyimport(), andisCloudfolds to a build-time constant, so non-cloud builds dead-code-eliminate the call and drop the module entirely.Verification
pnpm typecheck,pnpm lint,pnpm format,pnpm knip, andpnpm vitest run src/platform/telemetry/assertRumReporter.test.ts src/base/assert.test.ts(11 passed) are all green. New tests cover per-message dedupe, the 20-per-session cap, and synchronous error construction.This change is purely additive — it adds a reporting path and denies no capability, so there is no capability-denial claim to falsify.