diff --git a/static/app/utils/replays/replayReader.tsx b/static/app/utils/replays/replayReader.tsx index 53054698b4deff..8e1142b421b713 100644 --- a/static/app/utils/replays/replayReader.tsx +++ b/static/app/utils/replays/replayReader.tsx @@ -15,6 +15,7 @@ import { } from 'sentry/utils/replays/replayDataUtils'; import type { RecordingEvent, + RecordingOptions, ReplayError, ReplayRecord, ReplaySpan, @@ -151,11 +152,26 @@ export default class ReplayReader { getMemorySpans = memoize(() => this.sortedSpans.filter(isMemorySpan)); - isNetworkDetailsSetup = memoize(() => - this.getNetworkSpans().some( + sdkConfig = memoize(() => { + const found = this.rrwebEvents.find( + event => event.type === 5 && event.data.tag === 'options' + ) as undefined | RecordingOptions; + return found?.data?.payload; + }); + + isNetworkDetailsSetup = memoize(() => { + const config = this.sdkConfig(); + if (config) { + return this.sdkConfig()?.networkDetailHasUrls; + } + + // Network data was added in JS SDK 7.50.0 while sdkConfig was added in v7.51.1 + // So even if we don't have the config object, we should still fallback and + // look for spans with network data, as that means things are setup! + return this.getNetworkSpans().some( span => Object.keys(span.data.request?.headers || {}).length || Object.keys(span.data.response?.headers || {}).length - ) - ); + ); + }); } diff --git a/static/app/views/replays/types.tsx b/static/app/views/replays/types.tsx index 4647ac6f417e38..80fafb3d8d00d7 100644 --- a/static/app/views/replays/types.tsx +++ b/static/app/views/replays/types.tsx @@ -1,4 +1,4 @@ -import type {eventWithTime} from '@sentry-internal/rrweb/typings/types'; +import type {customEvent, eventWithTime} from '@sentry-internal/rrweb/typings/types'; import type {Duration} from 'moment'; import type {RawCrumb} from 'sentry/types/breadcrumbs'; @@ -155,6 +155,19 @@ export interface Highlight { } export type RecordingEvent = eventWithTime; +export type RecordingOptions = customEvent<{ + blockAllMedia: boolean; + errorSampleRate: number; + maskAllInputs: boolean; + maskAllText: boolean; + networkCaptureBodies: boolean; + networkDetailHasUrls: boolean; + networkRequestHasHeaders: boolean; + networkResponseHasHeaders: boolean; + sessionSampleRate: number; + useCompression: boolean; + useCompressionOption: boolean; +}>; export interface ReplaySpan> { data: T;