-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
Copy pathhandleGlobalEvent.ts
74 lines (63 loc) · 2.9 KB
/
handleGlobalEvent.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import type { Event, EventHint } from '@sentry/types';
import { DEBUG_BUILD } from '../debug-build';
import type { ReplayContainer } from '../types';
import { isErrorEvent, isFeedbackEvent, isReplayEvent, isTransactionEvent } from '../util/eventUtils';
import { isRrwebError } from '../util/isRrwebError';
import { logger } from '../util/logger';
import { addFeedbackBreadcrumb } from './util/addFeedbackBreadcrumb';
import { shouldSampleForBufferEvent } from './util/shouldSampleForBufferEvent';
/**
* Returns a listener to be added to `addEventProcessor(listener)`.
*/
export function handleGlobalEventListener(replay: ReplayContainer): (event: Event, hint: EventHint) => Event | null {
return Object.assign(
(event: Event, hint: EventHint) => {
// Do nothing if replay has been disabled or paused
if (!replay.isEnabled() || replay.isPaused()) {
return event;
}
if (isReplayEvent(event)) {
// Replays have separate set of breadcrumbs, do not include breadcrumbs
// from core SDK
delete event.breadcrumbs;
return event;
}
// We only want to handle errors, transactions, and feedbacks, nothing else
if (!isErrorEvent(event) && !isTransactionEvent(event) && !isFeedbackEvent(event)) {
return event;
}
// Ensure we do not add replay_id if the session is expired
const isSessionActive = replay.checkAndHandleExpiredSession();
if (!isSessionActive) {
return event;
}
if (isFeedbackEvent(event)) {
// This should never reject
// eslint-disable-next-line @typescript-eslint/no-floating-promises
replay.flush();
event.contexts.feedback.replay_id = replay.getSessionId();
// Add a replay breadcrumb for this piece of feedback
addFeedbackBreadcrumb(replay, event);
return event;
}
// Unless `captureExceptions` is enabled, we want to ignore errors coming from rrweb
// As there can be a bunch of stuff going wrong in internals there, that we don't want to bubble up to users
if (isRrwebError(event, hint) && !replay.getOptions()._experiments.captureExceptions) {
DEBUG_BUILD && logger.log('Ignoring error from rrweb internals', event);
return null;
}
// When in buffer mode, we decide to sample here.
// Later, in `handleAfterSendEvent`, if the replayId is set, we know that we sampled
// And convert the buffer session to a full session
const isErrorEventSampled = shouldSampleForBufferEvent(replay, event);
// Tag errors if it has been sampled in buffer mode, or if it is session mode
// Only tag transactions if in session mode
const shouldTagReplayId = isErrorEventSampled || replay.recordingMode === 'session';
if (shouldTagReplayId) {
event.tags = { ...event.tags, replayId: replay.getSessionId() };
}
return event;
},
{ id: 'Replay' },
);
}