|
1 | 1 | /* eslint-disable max-lines */ // TODO: We might want to split this file up |
2 | 2 | import type { BrowserClient, BrowserOptions } from '@sentry/browser'; |
3 | 3 | import { addGlobalEventProcessor, getCurrentHub, Scope, setContext } from '@sentry/core'; |
4 | | -import { Breadcrumb, Client, Event, Integration } from '@sentry/types'; |
| 4 | +import { Breadcrumb, Client, DataCategory, Event, EventDropReason, Integration } from '@sentry/types'; |
5 | 5 | import { addInstrumentationHandler, createEnvelope, logger } from '@sentry/utils'; |
6 | 6 | import debounce from 'lodash.debounce'; |
7 | 7 | import { PerformanceObserverEntryList } from 'perf_hooks'; |
@@ -126,6 +126,11 @@ export class Replay implements Integration { |
126 | 126 | */ |
127 | 127 | private stopRecording: ReturnType<typeof record> | null = null; |
128 | 128 |
|
| 129 | + /** |
| 130 | + * We overwrite `client.recordDroppedEvent`, but store the original method here so we can restore it. |
| 131 | + */ |
| 132 | + private _originalRecordDroppedEvent?: Client['recordDroppedEvent']; |
| 133 | + |
129 | 134 | private context: InternalEventContext = { |
130 | 135 | errorIds: new Set(), |
131 | 136 | traceIds: new Set(), |
@@ -405,6 +410,9 @@ export class Replay implements Integration { |
405 | 410 | WINDOW.addEventListener('blur', this.handleWindowBlur); |
406 | 411 | WINDOW.addEventListener('focus', this.handleWindowFocus); |
407 | 412 |
|
| 413 | + // We need to filter out dropped events captured by `addGlobalEventProcessor(this.handleGlobalEvent)` below |
| 414 | + this._overwriteRecordDroppedEvent(); |
| 415 | + |
408 | 416 | // There is no way to remove these listeners, so ensure they are only added once |
409 | 417 | if (!this.hasInitializedCoreListeners) { |
410 | 418 | // Listeners from core SDK // |
@@ -467,6 +475,8 @@ export class Replay implements Integration { |
467 | 475 | WINDOW.removeEventListener('blur', this.handleWindowBlur); |
468 | 476 | WINDOW.removeEventListener('focus', this.handleWindowFocus); |
469 | 477 |
|
| 478 | + this._restoreRecordDroppedEvent(); |
| 479 | + |
470 | 480 | if (this.performanceObserver) { |
471 | 481 | this.performanceObserver.disconnect(); |
472 | 482 | this.performanceObserver = null; |
@@ -1352,4 +1362,39 @@ export class Replay implements Integration { |
1352 | 1362 | this.options.errorSampleRate = opt.replaysOnErrorSampleRate; |
1353 | 1363 | } |
1354 | 1364 | } |
| 1365 | + |
| 1366 | + private _overwriteRecordDroppedEvent(): void { |
| 1367 | + const client = getCurrentHub().getClient(); |
| 1368 | + |
| 1369 | + if (!client) { |
| 1370 | + return; |
| 1371 | + } |
| 1372 | + |
| 1373 | + const _originalCallback = client.recordDroppedEvent.bind(client); |
| 1374 | + |
| 1375 | + const recordDroppedEvent: Client['recordDroppedEvent'] = ( |
| 1376 | + reason: EventDropReason, |
| 1377 | + category: DataCategory, |
| 1378 | + event?: Event, |
| 1379 | + ): void => { |
| 1380 | + if (event && event.event_id) { |
| 1381 | + this.context.errorIds.delete(event.event_id); |
| 1382 | + } |
| 1383 | + |
| 1384 | + return _originalCallback(reason, category, event); |
| 1385 | + }; |
| 1386 | + |
| 1387 | + client.recordDroppedEvent = recordDroppedEvent; |
| 1388 | + this._originalRecordDroppedEvent = _originalCallback; |
| 1389 | + } |
| 1390 | + |
| 1391 | + private _restoreRecordDroppedEvent(): void { |
| 1392 | + const client = getCurrentHub().getClient(); |
| 1393 | + |
| 1394 | + if (!client || !this._originalRecordDroppedEvent) { |
| 1395 | + return; |
| 1396 | + } |
| 1397 | + |
| 1398 | + client.recordDroppedEvent = this._originalRecordDroppedEvent; |
| 1399 | + } |
1355 | 1400 | } |
0 commit comments