Skip to content

Commit 7c4de55

Browse files
fix(sentry): use normalizeDepth config for nested object capture (#1143)
* fix(call): stringify console logs for Sentry breadcrumb capture Sentry's breadcrumb capture doesn't serialize nested objects from console.log - it just shows [Object] or [Array]. This makes the diagnostic logging useless for debugging AV issues. Changed all AV diagnostic console.log calls to use JSON.stringify: - Desired subscription state logging in Call.jsx - Status check logging in Call.jsx - Participant updated logging in eventLogger.js - AV issue reporting in FixAV.jsx The pretty-printed JSON (null, 2) ensures: 1. Sentry breadcrumbs capture full data as readable strings 2. Local console output remains human-readable for debugging Fixes #1142 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * fix(sentry): use normalizeDepth config instead of JSON.stringify Replace JSON.stringify logging with Sentry normalizeDepth configuration to properly capture nested objects in breadcrumbs and error reports. Changes: - Add normalizeDepth: 6 to Sentry.init() to handle 4-6 level objects - Revert JSON.stringify calls in Call.jsx, eventLogger.js, and FixAV.jsx - Add module-level ref for desired subscription state tracking - Include desiredSubscriptions in FixAV error reports for diagnosing mismatches between layout-computed and actual subscription states This approach is cleaner and preserves object structure in Sentry UI, making it easier to diagnose AV issues. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * update test cases --------- Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 98d5110 commit 7c4de55

5 files changed

Lines changed: 41 additions & 3 deletions

File tree

client/src/call/Call.jsx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,23 @@ import { computePixelsForLayout } from "./layouts/computePixelsForLayout";
1414
import { Tile } from "./Tile";
1515
import { useStageEventLogger } from "./hooks/eventLogger";
1616

17+
/**
18+
* Module-level ref for diagnostic access to desired subscription state.
19+
*
20+
* This allows FixAV error reporting to capture what subscriptions SHOULD be
21+
* (based on layout) vs what they actually are (from Daily API), without
22+
* adding React context complexity for a single diagnostic use case.
23+
*
24+
* The Map stores: dailyId → { audio: boolean, video: boolean, screenVideo: boolean }
25+
*
26+
* Why use a module-level ref instead of React context?
27+
* - Only one piece of diagnostic state needs sharing between components
28+
* - Avoids the overhead of creating a context provider/consumer
29+
* - Easy to refactor to context later if we need more shared state
30+
* - Simpler and more pragmatic for this specific debugging scenario
31+
*/
32+
export const latestDesiredSubscriptions = { current: new Map() };
33+
1734
export function Call({ showSelfView = true, layout, rooms }) {
1835
// ------------------- measure container size ---------------------
1936
const containerRef = useRef(null);
@@ -312,6 +329,9 @@ export function Call({ showSelfView = true, layout, rooms }) {
312329
nextSubscriptions.set(dailyId, tracks);
313330
});
314331

332+
// Store desired subscriptions in module-level ref for FixAV error reporting
333+
latestDesiredSubscriptions.current = nextSubscriptions;
334+
315335
// Log desired subscription state for debugging (appears in Sentry breadcrumbs)
316336
// Only log when the desired state actually changes to avoid spam
317337
const desiredStateSignature = JSON.stringify(

client/src/call/FixAV.jsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React, { useCallback, useState } from "react";
22
import * as Sentry from "@sentry/react";
33
import { useDaily, useLocalSessionId } from "@daily-co/daily-react";
44
import { Button } from "../components/Button";
5+
import { latestDesiredSubscriptions } from "./Call";
56

67
/**
78
* Hook for reporting audio/video issues to Sentry and refreshing the page.
@@ -45,9 +46,17 @@ export function useFixAV() {
4546
},
4647
}));
4748

49+
// Convert desired subscriptions Map to a plain object for Sentry.
50+
// The Map stores what tracks SHOULD be subscribed based on layout,
51+
// which helps diagnose mismatches between desired and actual state.
52+
const desiredSubscriptions = Object.fromEntries(
53+
latestDesiredSubscriptions.current || new Map()
54+
);
55+
4856
const reportData = {
4957
userReportedIssues: selectedIssues,
5058
participants: participantSummary,
59+
desiredSubscriptions,
5160
meetingState: callObject?.meetingState?.(),
5261
localSessionId,
5362
};

client/src/index.jsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,15 @@ Sentry.init({
2323
// We recommend adjusting this value in production
2424
tracesSampleRate: 0.1,
2525
enabled: process.env.NODE_ENV === "production",
26+
27+
// Increase depth for serializing nested objects in breadcrumbs and event extras.
28+
// Default is 3 levels, which was causing objects in AV diagnostic logs to appear
29+
// as [Object] instead of their actual data. Setting to 6 ensures we capture:
30+
// - Desired subscription state (2-3 levels: dailyId → {a, v})
31+
// - Status check arrays (4 levels: array → object → {desired/actual} → properties)
32+
// - Participant data (4 levels: participants → array → object → track properties)
33+
// See: https://docs.sentry.io/platforms/javascript/configuration/apis/
34+
normalizeDepth: 6,
2635
});
2736

2837
// Todo: can we move this button to a separate file?

cypress/fixtures/mockCDN/demo/annotated_demo/demo.treatments.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ templates:
6969
displayTime: 5
7070

7171
- name: Discussion
72-
duration: 900
72+
duration: 1200
7373
discussion: # this section describes the video chat that takes place during the discussion stage
7474
chatType: video # you can also have just a text chat
7575
showNickname: true # you can choose to show or hide the names participants gave themselves

cypress/fixtures/mockCDN/test/subscriptionHell/test.config.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
"customIdInstructions": "none",
66
"platformConsent": "US",
77
"consentAddendum": "none",
8-
"checkAudio": false,
9-
"checkVideo": false,
8+
"checkAudio": true,
9+
"checkVideo": true,
1010
"introSequence": "subscription_hell_intro",
1111
"treatments": ["subscription_hell_test"],
1212
"payoffs": "equal",

0 commit comments

Comments
 (0)