Skip to content

Commit

Permalink
fix(replay): Handle errors in beforeAddRecordingEvent callback
Browse files Browse the repository at this point in the history
  • Loading branch information
mydea committed Jul 17, 2023
1 parent 2b4121f commit df40646
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 12 deletions.
24 changes: 19 additions & 5 deletions packages/replay/src/util/addEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { getCurrentHub } from '@sentry/core';
import { logger } from '@sentry/utils';

import { EventBufferSizeExceededError } from '../eventBuffer/error';
import type { AddEventResult, RecordingEvent, ReplayContainer, ReplayFrameEvent } from '../types';
import type { AddEventResult, RecordingEvent, ReplayContainer, ReplayFrameEvent, ReplayPluginOptions } from '../types';
import { timestampToMs } from './timestampToMs';

function isCustomEvent(event: RecordingEvent): event is ReplayFrameEvent {
Expand Down Expand Up @@ -46,10 +46,7 @@ export async function addEvent(

const replayOptions = replay.getOptions();

const eventAfterPossibleCallback =
typeof replayOptions.beforeAddRecordingEvent === 'function' && isCustomEvent(event)
? replayOptions.beforeAddRecordingEvent(event)
: event;
const eventAfterPossibleCallback = maybeApplyCallback(event, replayOptions.beforeAddRecordingEvent);

if (!eventAfterPossibleCallback) {
return;
Expand All @@ -69,3 +66,20 @@ export async function addEvent(
}
}
}

function maybeApplyCallback(
event: RecordingEvent,
callback: ReplayPluginOptions['beforeAddRecordingEvent'],
): RecordingEvent | null | undefined {
try {
if (typeof callback === 'function' && isCustomEvent(event)) {
return callback(event);
}
} catch (error) {
__DEBUG_BUILD__ &&
logger.error('[Replay] An error occured in the `beforeAddRecordingEvent` callback, skipping the event...', error);
return null;
}

return event;
}
51 changes: 44 additions & 7 deletions packages/replay/test/integration/beforeAddRecordingEvent.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import * as SentryUtils from '@sentry/utils';
import type { Replay } from '../../src';
import type { ReplayContainer } from '../../src/replay';
import { clearSession } from '../../src/session/clearSession';
import type { EventType } from '../../src/types';
import { createPerformanceEntries } from '../../src/util/createPerformanceEntries';
import { createPerformanceSpans } from '../../src/util/createPerformanceSpans';
import * as SendReplayRequest from '../../src/util/sendReplayRequest';
import { BASE_TIMESTAMP, mockRrweb, mockSdk } from '../index';
import { useFakeTimers } from '../utils/use-fake-timers';
Expand Down Expand Up @@ -40,6 +41,10 @@ describe('Integration | beforeAddRecordingEvent', () => {
beforeAddRecordingEvent: event => {
const eventData = event.data;

if (eventData.tag === 'performanceSpan') {
throw new Error('test error in callback');
}

if (eventData.tag === 'breadcrumb' && eventData.payload.category === 'ui.click') {
return {
...event,
Expand All @@ -53,12 +58,6 @@ describe('Integration | beforeAddRecordingEvent', () => {
};
}

// This should not do anything because callback should not be called
// for `event.type != 5` - but we guard anyhow to be safe
if ((event.type as EventType) === 2) {
return null;
}

if (eventData.tag === 'options') {
return null;
}
Expand Down Expand Up @@ -143,4 +142,42 @@ describe('Integration | beforeAddRecordingEvent', () => {
recordingData: JSON.stringify([{ data: { isCheckout: true }, timestamp: BASE_TIMESTAMP, type: 2 }]),
});
});

it('handles error in callback', async () => {
createPerformanceSpans(
replay,
createPerformanceEntries([
{
name: 'https://sentry.io/foo.js',
entryType: 'resource',
startTime: 176.59999990463257,
duration: 5.600000023841858,
initiatorType: 'link',
nextHopProtocol: 'h2',
workerStart: 177.5,
redirectStart: 0,
redirectEnd: 0,
fetchStart: 177.69999992847443,
domainLookupStart: 177.69999992847443,
domainLookupEnd: 177.69999992847443,
connectStart: 177.69999992847443,
connectEnd: 177.69999992847443,
secureConnectionStart: 177.69999992847443,
requestStart: 177.5,
responseStart: 181,
responseEnd: 182.19999992847443,
transferSize: 0,
encodedBodySize: 0,
decodedBodySize: 0,
serverTiming: [],
} as unknown as PerformanceResourceTiming,
]),
);

jest.runAllTimers();
await new Promise(process.nextTick);

expect(replay).not.toHaveLastSentReplay();
expect(replay.isEnabled()).toBe(true);
});
});

0 comments on commit df40646

Please sign in to comment.