-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
/
Copy pathhandleNetworkBreadcrumbs.ts
101 lines (86 loc) · 3.49 KB
/
handleNetworkBreadcrumbs.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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import type { FetchHint, XhrHint } from '@sentry-internal/browser-utils';
import { getClient } from '@sentry/core';
import type { Breadcrumb, BreadcrumbHint, FetchBreadcrumbData, XhrBreadcrumbData } from '@sentry/core';
import { DEBUG_BUILD } from '../debug-build';
import type { ReplayContainer, ReplayNetworkOptions } from '../types';
import { logger } from '../util/logger';
import { captureFetchBreadcrumbToReplay, enrichFetchBreadcrumb } from './util/fetchUtils';
import { captureXhrBreadcrumbToReplay, enrichXhrBreadcrumb } from './util/xhrUtils';
interface ExtendedNetworkBreadcrumbsOptions extends ReplayNetworkOptions {
replay: ReplayContainer;
}
/**
* This method does two things:
* - It enriches the regular XHR/fetch breadcrumbs with request/response size data
* - It captures the XHR/fetch breadcrumbs to the replay
* (enriching it with further data that is _not_ added to the regular breadcrumbs)
*/
export function handleNetworkBreadcrumbs(replay: ReplayContainer): void {
const client = getClient();
try {
const {
networkDetailAllowUrls,
networkDetailDenyUrls,
networkCaptureBodies,
networkRequestHeaders,
networkResponseHeaders,
} = replay.getOptions();
const options: ExtendedNetworkBreadcrumbsOptions = {
replay,
networkDetailAllowUrls,
networkDetailDenyUrls,
networkCaptureBodies,
networkRequestHeaders,
networkResponseHeaders,
};
if (client) {
client.on('beforeAddBreadcrumb', (breadcrumb, hint) => beforeAddNetworkBreadcrumb(options, breadcrumb, hint));
}
} catch {
// Do nothing
}
}
/** just exported for tests */
export function beforeAddNetworkBreadcrumb(
options: ExtendedNetworkBreadcrumbsOptions,
breadcrumb: Breadcrumb,
hint?: BreadcrumbHint,
): void {
if (!breadcrumb.data) {
return;
}
try {
if (_isXhrBreadcrumb(breadcrumb) && _isXhrHint(hint)) {
// This has to be sync, as we need to ensure the breadcrumb is enriched in the same tick
// Because the hook runs synchronously, and the breadcrumb is afterwards passed on
// So any async mutations to it will not be reflected in the final breadcrumb
enrichXhrBreadcrumb(breadcrumb, hint);
// This call should not reject
// eslint-disable-next-line @typescript-eslint/no-floating-promises
captureXhrBreadcrumbToReplay(breadcrumb, hint, options);
}
if (_isFetchBreadcrumb(breadcrumb) && _isFetchHint(hint)) {
// This has to be sync, as we need to ensure the breadcrumb is enriched in the same tick
// Because the hook runs synchronously, and the breadcrumb is afterwards passed on
// So any async mutations to it will not be reflected in the final breadcrumb
enrichFetchBreadcrumb(breadcrumb, hint);
// This call should not reject
// eslint-disable-next-line @typescript-eslint/no-floating-promises
captureFetchBreadcrumbToReplay(breadcrumb, hint, options);
}
} catch (e) {
DEBUG_BUILD && logger.exception(e, 'Error when enriching network breadcrumb');
}
}
function _isXhrBreadcrumb(breadcrumb: Breadcrumb): breadcrumb is Breadcrumb & { data: XhrBreadcrumbData } {
return breadcrumb.category === 'xhr';
}
function _isFetchBreadcrumb(breadcrumb: Breadcrumb): breadcrumb is Breadcrumb & { data: FetchBreadcrumbData } {
return breadcrumb.category === 'fetch';
}
function _isXhrHint(hint?: BreadcrumbHint): hint is XhrHint {
return hint?.xhr;
}
function _isFetchHint(hint?: BreadcrumbHint): hint is FetchHint {
return hint?.response;
}