@sentry/replay 7.104.0 → 8.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/cjs/index.js +128 -258
- package/cjs/index.js.map +1 -1
- package/esm/index.js +130 -260
- package/esm/index.js.map +1 -1
- package/package.json +7 -7
- package/types/coreHandlers/handleBreadcrumbs.d.ts +14 -0
- package/types/coreHandlers/handleBreadcrumbs.d.ts.map +1 -0
- package/types/coreHandlers/handleGlobalEvent.d.ts +1 -1
- package/types/coreHandlers/handleGlobalEvent.d.ts.map +1 -1
- package/types/coreHandlers/handleNetworkBreadcrumbs.d.ts +1 -2
- package/types/coreHandlers/handleNetworkBreadcrumbs.d.ts.map +1 -1
- package/types/coreHandlers/util/fetchUtils.d.ts +3 -8
- package/types/coreHandlers/util/fetchUtils.d.ts.map +1 -1
- package/types/coreHandlers/util/networkUtils.d.ts +1 -2
- package/types/coreHandlers/util/networkUtils.d.ts.map +1 -1
- package/types/coreHandlers/util/xhrUtils.d.ts +2 -4
- package/types/coreHandlers/util/xhrUtils.d.ts.map +1 -1
- package/types/util/addGlobalListeners.d.ts.map +1 -1
- package/types/util/getReplay.d.ts.map +1 -1
- package/types/util/prepareReplayEvent.d.ts +2 -2
- package/types/util/prepareReplayEvent.d.ts.map +1 -1
- package/types-ts3.8/coreHandlers/handleBreadcrumbs.d.ts +14 -0
- package/types-ts3.8/coreHandlers/handleGlobalEvent.d.ts +1 -1
- package/types-ts3.8/coreHandlers/handleNetworkBreadcrumbs.d.ts +1 -2
- package/types-ts3.8/coreHandlers/util/fetchUtils.d.ts +3 -8
- package/types-ts3.8/coreHandlers/util/networkUtils.d.ts +1 -2
- package/types-ts3.8/coreHandlers/util/xhrUtils.d.ts +2 -4
- package/types-ts3.8/util/prepareReplayEvent.d.ts +2 -2
- package/types/coreHandlers/handleFetch.d.ts +0 -9
- package/types/coreHandlers/handleFetch.d.ts.map +0 -1
- package/types/coreHandlers/handleScope.d.ts +0 -13
- package/types/coreHandlers/handleScope.d.ts.map +0 -1
- package/types/coreHandlers/handleXhr.d.ts +0 -9
- package/types/coreHandlers/handleXhr.d.ts.map +0 -1
- package/types-ts3.8/coreHandlers/handleFetch.d.ts +0 -9
- package/types-ts3.8/coreHandlers/handleScope.d.ts +0 -13
- package/types-ts3.8/coreHandlers/handleXhr.d.ts +0 -9
package/README.md
CHANGED
package/cjs/index.js
CHANGED
|
@@ -5835,6 +5835,112 @@ function handleHydrationError(replay, event) {
|
|
|
5835
5835
|
}
|
|
5836
5836
|
}
|
|
5837
5837
|
|
|
5838
|
+
/**
|
|
5839
|
+
* Handle breadcrumbs that Sentry captures, and make sure to capture relevant breadcrumbs to Replay as well.
|
|
5840
|
+
*/
|
|
5841
|
+
function handleBreadcrumbs(replay) {
|
|
5842
|
+
const client = core.getClient();
|
|
5843
|
+
|
|
5844
|
+
if (!client) {
|
|
5845
|
+
return;
|
|
5846
|
+
}
|
|
5847
|
+
|
|
5848
|
+
client.on('beforeAddBreadcrumb', breadcrumb => beforeAddBreadcrumb(replay, breadcrumb));
|
|
5849
|
+
}
|
|
5850
|
+
|
|
5851
|
+
function beforeAddBreadcrumb(replay, breadcrumb) {
|
|
5852
|
+
if (!replay.isEnabled() || !isBreadcrumbWithCategory(breadcrumb)) {
|
|
5853
|
+
return;
|
|
5854
|
+
}
|
|
5855
|
+
|
|
5856
|
+
const result = normalizeBreadcrumb(breadcrumb);
|
|
5857
|
+
if (result) {
|
|
5858
|
+
addBreadcrumbEvent(replay, result);
|
|
5859
|
+
}
|
|
5860
|
+
}
|
|
5861
|
+
|
|
5862
|
+
/** Exported only for tests. */
|
|
5863
|
+
function normalizeBreadcrumb(breadcrumb) {
|
|
5864
|
+
if (
|
|
5865
|
+
!isBreadcrumbWithCategory(breadcrumb) ||
|
|
5866
|
+
[
|
|
5867
|
+
// fetch & xhr are handled separately,in handleNetworkBreadcrumbs
|
|
5868
|
+
'fetch',
|
|
5869
|
+
'xhr',
|
|
5870
|
+
// These two are breadcrumbs for emitted sentry events, we don't care about them
|
|
5871
|
+
'sentry.event',
|
|
5872
|
+
'sentry.transaction',
|
|
5873
|
+
].includes(breadcrumb.category) ||
|
|
5874
|
+
// We capture UI breadcrumbs separately
|
|
5875
|
+
breadcrumb.category.startsWith('ui.')
|
|
5876
|
+
) {
|
|
5877
|
+
return null;
|
|
5878
|
+
}
|
|
5879
|
+
|
|
5880
|
+
if (breadcrumb.category === 'console') {
|
|
5881
|
+
return normalizeConsoleBreadcrumb(breadcrumb);
|
|
5882
|
+
}
|
|
5883
|
+
|
|
5884
|
+
return createBreadcrumb(breadcrumb);
|
|
5885
|
+
}
|
|
5886
|
+
|
|
5887
|
+
/** exported for tests only */
|
|
5888
|
+
function normalizeConsoleBreadcrumb(
|
|
5889
|
+
breadcrumb,
|
|
5890
|
+
) {
|
|
5891
|
+
const args = breadcrumb.data && breadcrumb.data.arguments;
|
|
5892
|
+
|
|
5893
|
+
if (!Array.isArray(args) || args.length === 0) {
|
|
5894
|
+
return createBreadcrumb(breadcrumb);
|
|
5895
|
+
}
|
|
5896
|
+
|
|
5897
|
+
let isTruncated = false;
|
|
5898
|
+
|
|
5899
|
+
// Avoid giant args captures
|
|
5900
|
+
const normalizedArgs = args.map(arg => {
|
|
5901
|
+
if (!arg) {
|
|
5902
|
+
return arg;
|
|
5903
|
+
}
|
|
5904
|
+
if (typeof arg === 'string') {
|
|
5905
|
+
if (arg.length > CONSOLE_ARG_MAX_SIZE) {
|
|
5906
|
+
isTruncated = true;
|
|
5907
|
+
return `${arg.slice(0, CONSOLE_ARG_MAX_SIZE)}…`;
|
|
5908
|
+
}
|
|
5909
|
+
|
|
5910
|
+
return arg;
|
|
5911
|
+
}
|
|
5912
|
+
if (typeof arg === 'object') {
|
|
5913
|
+
try {
|
|
5914
|
+
const normalizedArg = utils.normalize(arg, 7);
|
|
5915
|
+
const stringified = JSON.stringify(normalizedArg);
|
|
5916
|
+
if (stringified.length > CONSOLE_ARG_MAX_SIZE) {
|
|
5917
|
+
isTruncated = true;
|
|
5918
|
+
// We use the pretty printed JSON string here as a base
|
|
5919
|
+
return `${JSON.stringify(normalizedArg, null, 2).slice(0, CONSOLE_ARG_MAX_SIZE)}…`;
|
|
5920
|
+
}
|
|
5921
|
+
return normalizedArg;
|
|
5922
|
+
} catch (e) {
|
|
5923
|
+
// fall back to default
|
|
5924
|
+
}
|
|
5925
|
+
}
|
|
5926
|
+
|
|
5927
|
+
return arg;
|
|
5928
|
+
});
|
|
5929
|
+
|
|
5930
|
+
return createBreadcrumb({
|
|
5931
|
+
...breadcrumb,
|
|
5932
|
+
data: {
|
|
5933
|
+
...breadcrumb.data,
|
|
5934
|
+
arguments: normalizedArgs,
|
|
5935
|
+
...(isTruncated ? { _meta: { warnings: ['CONSOLE_ARG_TRUNCATED'] } } : {}),
|
|
5936
|
+
},
|
|
5937
|
+
});
|
|
5938
|
+
}
|
|
5939
|
+
|
|
5940
|
+
function isBreadcrumbWithCategory(breadcrumb) {
|
|
5941
|
+
return !!breadcrumb.category;
|
|
5942
|
+
}
|
|
5943
|
+
|
|
5838
5944
|
/**
|
|
5839
5945
|
* Returns true if we think the given event is an error originating inside of rrweb.
|
|
5840
5946
|
*/
|
|
@@ -5912,12 +6018,7 @@ function shouldSampleForBufferEvent(replay, event) {
|
|
|
5912
6018
|
/**
|
|
5913
6019
|
* Returns a listener to be added to `addEventProcessor(listener)`.
|
|
5914
6020
|
*/
|
|
5915
|
-
function handleGlobalEventListener(
|
|
5916
|
-
replay,
|
|
5917
|
-
includeAfterSendEventHandling = false,
|
|
5918
|
-
) {
|
|
5919
|
-
const afterSendHandler = includeAfterSendEventHandling ? handleAfterSendEvent(replay) : undefined;
|
|
5920
|
-
|
|
6021
|
+
function handleGlobalEventListener(replay) {
|
|
5921
6022
|
return Object.assign(
|
|
5922
6023
|
(event, hint) => {
|
|
5923
6024
|
// Do nothing if replay has been disabled
|
|
@@ -5973,13 +6074,6 @@ function handleGlobalEventListener(
|
|
|
5973
6074
|
event.tags = { ...event.tags, replayId: replay.getSessionId() };
|
|
5974
6075
|
}
|
|
5975
6076
|
|
|
5976
|
-
// In cases where a custom client is used that does not support the new hooks (yet),
|
|
5977
|
-
// we manually call this hook method here
|
|
5978
|
-
if (afterSendHandler) {
|
|
5979
|
-
// Pretend the error had a 200 response so we always capture it
|
|
5980
|
-
afterSendHandler(event, { statusCode: 200 });
|
|
5981
|
-
}
|
|
5982
|
-
|
|
5983
6077
|
return event;
|
|
5984
6078
|
},
|
|
5985
6079
|
{ id: 'Replay' },
|
|
@@ -6096,97 +6190,14 @@ function addNetworkBreadcrumb(
|
|
|
6096
6190
|
});
|
|
6097
6191
|
}
|
|
6098
6192
|
|
|
6099
|
-
/** only exported for tests */
|
|
6100
|
-
function handleFetch(handlerData) {
|
|
6101
|
-
const { startTimestamp, endTimestamp, fetchData, response } = handlerData;
|
|
6102
|
-
|
|
6103
|
-
if (!endTimestamp) {
|
|
6104
|
-
return null;
|
|
6105
|
-
}
|
|
6106
|
-
|
|
6107
|
-
// This is only used as a fallback, so we know the body sizes are never set here
|
|
6108
|
-
const { method, url } = fetchData;
|
|
6109
|
-
|
|
6110
|
-
return {
|
|
6111
|
-
type: 'resource.fetch',
|
|
6112
|
-
start: startTimestamp / 1000,
|
|
6113
|
-
end: endTimestamp / 1000,
|
|
6114
|
-
name: url,
|
|
6115
|
-
data: {
|
|
6116
|
-
method,
|
|
6117
|
-
statusCode: response ? (response ).status : undefined,
|
|
6118
|
-
},
|
|
6119
|
-
};
|
|
6120
|
-
}
|
|
6121
|
-
|
|
6122
|
-
/**
|
|
6123
|
-
* Returns a listener to be added to `addFetchInstrumentationHandler(listener)`.
|
|
6124
|
-
*/
|
|
6125
|
-
function handleFetchSpanListener(replay) {
|
|
6126
|
-
return (handlerData) => {
|
|
6127
|
-
if (!replay.isEnabled()) {
|
|
6128
|
-
return;
|
|
6129
|
-
}
|
|
6130
|
-
|
|
6131
|
-
const result = handleFetch(handlerData);
|
|
6132
|
-
|
|
6133
|
-
addNetworkBreadcrumb(replay, result);
|
|
6134
|
-
};
|
|
6135
|
-
}
|
|
6136
|
-
|
|
6137
|
-
/** only exported for tests */
|
|
6138
|
-
function handleXhr(handlerData) {
|
|
6139
|
-
const { startTimestamp, endTimestamp, xhr } = handlerData;
|
|
6140
|
-
|
|
6141
|
-
const sentryXhrData = xhr[utils.SENTRY_XHR_DATA_KEY];
|
|
6142
|
-
|
|
6143
|
-
if (!startTimestamp || !endTimestamp || !sentryXhrData) {
|
|
6144
|
-
return null;
|
|
6145
|
-
}
|
|
6146
|
-
|
|
6147
|
-
// This is only used as a fallback, so we know the body sizes are never set here
|
|
6148
|
-
const { method, url, status_code: statusCode } = sentryXhrData;
|
|
6149
|
-
|
|
6150
|
-
if (url === undefined) {
|
|
6151
|
-
return null;
|
|
6152
|
-
}
|
|
6153
|
-
|
|
6154
|
-
return {
|
|
6155
|
-
type: 'resource.xhr',
|
|
6156
|
-
name: url,
|
|
6157
|
-
start: startTimestamp / 1000,
|
|
6158
|
-
end: endTimestamp / 1000,
|
|
6159
|
-
data: {
|
|
6160
|
-
method,
|
|
6161
|
-
statusCode,
|
|
6162
|
-
},
|
|
6163
|
-
};
|
|
6164
|
-
}
|
|
6165
|
-
|
|
6166
|
-
/**
|
|
6167
|
-
* Returns a listener to be added to `addXhrInstrumentationHandler(listener)`.
|
|
6168
|
-
*/
|
|
6169
|
-
function handleXhrSpanListener(replay) {
|
|
6170
|
-
return (handlerData) => {
|
|
6171
|
-
if (!replay.isEnabled()) {
|
|
6172
|
-
return;
|
|
6173
|
-
}
|
|
6174
|
-
|
|
6175
|
-
const result = handleXhr(handlerData);
|
|
6176
|
-
|
|
6177
|
-
addNetworkBreadcrumb(replay, result);
|
|
6178
|
-
};
|
|
6179
|
-
}
|
|
6180
|
-
|
|
6181
6193
|
/** Get the size of a body. */
|
|
6182
|
-
function getBodySize(
|
|
6183
|
-
body,
|
|
6184
|
-
textEncoder,
|
|
6185
|
-
) {
|
|
6194
|
+
function getBodySize(body) {
|
|
6186
6195
|
if (!body) {
|
|
6187
6196
|
return undefined;
|
|
6188
6197
|
}
|
|
6189
6198
|
|
|
6199
|
+
const textEncoder = new TextEncoder();
|
|
6200
|
+
|
|
6190
6201
|
try {
|
|
6191
6202
|
if (typeof body === 'string') {
|
|
6192
6203
|
return textEncoder.encode(body).length;
|
|
@@ -6486,12 +6497,11 @@ async function captureFetchBreadcrumbToReplay(
|
|
|
6486
6497
|
function enrichFetchBreadcrumb(
|
|
6487
6498
|
breadcrumb,
|
|
6488
6499
|
hint,
|
|
6489
|
-
options,
|
|
6490
6500
|
) {
|
|
6491
6501
|
const { input, response } = hint;
|
|
6492
6502
|
|
|
6493
6503
|
const body = input ? _getFetchRequestArgBody(input) : undefined;
|
|
6494
|
-
const reqSize = getBodySize(body
|
|
6504
|
+
const reqSize = getBodySize(body);
|
|
6495
6505
|
|
|
6496
6506
|
const resSize = response ? parseContentLengthHeader(response.headers.get('content-length')) : undefined;
|
|
6497
6507
|
|
|
@@ -6506,9 +6516,7 @@ function enrichFetchBreadcrumb(
|
|
|
6506
6516
|
async function _prepareFetchData(
|
|
6507
6517
|
breadcrumb,
|
|
6508
6518
|
hint,
|
|
6509
|
-
options
|
|
6510
|
-
|
|
6511
|
-
,
|
|
6519
|
+
options,
|
|
6512
6520
|
) {
|
|
6513
6521
|
const now = Date.now();
|
|
6514
6522
|
const { startTimestamp = now, endTimestamp = now } = hint;
|
|
@@ -6568,11 +6576,8 @@ async function _getResponseInfo(
|
|
|
6568
6576
|
captureDetails,
|
|
6569
6577
|
{
|
|
6570
6578
|
networkCaptureBodies,
|
|
6571
|
-
textEncoder,
|
|
6572
6579
|
networkResponseHeaders,
|
|
6573
|
-
}
|
|
6574
|
-
|
|
6575
|
-
,
|
|
6580
|
+
},
|
|
6576
6581
|
response,
|
|
6577
6582
|
responseBodySize,
|
|
6578
6583
|
) {
|
|
@@ -6589,7 +6594,7 @@ async function _getResponseInfo(
|
|
|
6589
6594
|
const [bodyText, warning] = await _parseFetchResponseBody(response);
|
|
6590
6595
|
const result = getResponseData(bodyText, {
|
|
6591
6596
|
networkCaptureBodies,
|
|
6592
|
-
|
|
6597
|
+
|
|
6593
6598
|
responseBodySize,
|
|
6594
6599
|
captureDetails,
|
|
6595
6600
|
headers,
|
|
@@ -6606,7 +6611,6 @@ function getResponseData(
|
|
|
6606
6611
|
bodyText,
|
|
6607
6612
|
{
|
|
6608
6613
|
networkCaptureBodies,
|
|
6609
|
-
textEncoder,
|
|
6610
6614
|
responseBodySize,
|
|
6611
6615
|
captureDetails,
|
|
6612
6616
|
headers,
|
|
@@ -6616,9 +6620,7 @@ function getResponseData(
|
|
|
6616
6620
|
) {
|
|
6617
6621
|
try {
|
|
6618
6622
|
const size =
|
|
6619
|
-
bodyText && bodyText.length && responseBodySize === undefined
|
|
6620
|
-
? getBodySize(bodyText, textEncoder)
|
|
6621
|
-
: responseBodySize;
|
|
6623
|
+
bodyText && bodyText.length && responseBodySize === undefined ? getBodySize(bodyText) : responseBodySize;
|
|
6622
6624
|
|
|
6623
6625
|
if (!captureDetails) {
|
|
6624
6626
|
return buildSkippedNetworkRequestOrResponse(size);
|
|
@@ -6773,7 +6775,6 @@ async function captureXhrBreadcrumbToReplay(
|
|
|
6773
6775
|
function enrichXhrBreadcrumb(
|
|
6774
6776
|
breadcrumb,
|
|
6775
6777
|
hint,
|
|
6776
|
-
options,
|
|
6777
6778
|
) {
|
|
6778
6779
|
const { xhr, input } = hint;
|
|
6779
6780
|
|
|
@@ -6781,10 +6782,10 @@ function enrichXhrBreadcrumb(
|
|
|
6781
6782
|
return;
|
|
6782
6783
|
}
|
|
6783
6784
|
|
|
6784
|
-
const reqSize = getBodySize(input
|
|
6785
|
+
const reqSize = getBodySize(input);
|
|
6785
6786
|
const resSize = xhr.getResponseHeader('content-length')
|
|
6786
6787
|
? parseContentLengthHeader(xhr.getResponseHeader('content-length'))
|
|
6787
|
-
: _getBodySize(xhr.response, xhr.responseType
|
|
6788
|
+
: _getBodySize(xhr.response, xhr.responseType);
|
|
6788
6789
|
|
|
6789
6790
|
if (reqSize !== undefined) {
|
|
6790
6791
|
breadcrumb.data.request_body_size = reqSize;
|
|
@@ -6931,11 +6932,10 @@ function _parseXhrResponse(
|
|
|
6931
6932
|
function _getBodySize(
|
|
6932
6933
|
body,
|
|
6933
6934
|
responseType,
|
|
6934
|
-
textEncoder,
|
|
6935
6935
|
) {
|
|
6936
6936
|
try {
|
|
6937
6937
|
const bodyStr = responseType === 'json' && body && typeof body === 'object' ? JSON.stringify(body) : body;
|
|
6938
|
-
return getBodySize(bodyStr
|
|
6938
|
+
return getBodySize(bodyStr);
|
|
6939
6939
|
} catch (e3) {
|
|
6940
6940
|
return undefined;
|
|
6941
6941
|
}
|
|
@@ -6951,8 +6951,6 @@ function handleNetworkBreadcrumbs(replay) {
|
|
|
6951
6951
|
const client = core.getClient();
|
|
6952
6952
|
|
|
6953
6953
|
try {
|
|
6954
|
-
const textEncoder = new TextEncoder();
|
|
6955
|
-
|
|
6956
6954
|
const {
|
|
6957
6955
|
networkDetailAllowUrls,
|
|
6958
6956
|
networkDetailDenyUrls,
|
|
@@ -6963,7 +6961,6 @@ function handleNetworkBreadcrumbs(replay) {
|
|
|
6963
6961
|
|
|
6964
6962
|
const options = {
|
|
6965
6963
|
replay,
|
|
6966
|
-
textEncoder,
|
|
6967
6964
|
networkDetailAllowUrls,
|
|
6968
6965
|
networkDetailDenyUrls,
|
|
6969
6966
|
networkCaptureBodies,
|
|
@@ -6971,12 +6968,8 @@ function handleNetworkBreadcrumbs(replay) {
|
|
|
6971
6968
|
networkResponseHeaders,
|
|
6972
6969
|
};
|
|
6973
6970
|
|
|
6974
|
-
if (client
|
|
6971
|
+
if (client) {
|
|
6975
6972
|
client.on('beforeAddBreadcrumb', (breadcrumb, hint) => beforeAddNetworkBreadcrumb(options, breadcrumb, hint));
|
|
6976
|
-
} else {
|
|
6977
|
-
// Fallback behavior
|
|
6978
|
-
utils.addFetchInstrumentationHandler(handleFetchSpanListener(replay));
|
|
6979
|
-
utils.addXhrInstrumentationHandler(handleXhrSpanListener(replay));
|
|
6980
6973
|
}
|
|
6981
6974
|
} catch (e2) {
|
|
6982
6975
|
// Do nothing
|
|
@@ -6998,7 +6991,7 @@ function beforeAddNetworkBreadcrumb(
|
|
|
6998
6991
|
// This has to be sync, as we need to ensure the breadcrumb is enriched in the same tick
|
|
6999
6992
|
// Because the hook runs synchronously, and the breadcrumb is afterwards passed on
|
|
7000
6993
|
// So any async mutations to it will not be reflected in the final breadcrumb
|
|
7001
|
-
enrichXhrBreadcrumb(breadcrumb, hint
|
|
6994
|
+
enrichXhrBreadcrumb(breadcrumb, hint);
|
|
7002
6995
|
|
|
7003
6996
|
// This call should not reject
|
|
7004
6997
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
@@ -7009,7 +7002,7 @@ function beforeAddNetworkBreadcrumb(
|
|
|
7009
7002
|
// This has to be sync, as we need to ensure the breadcrumb is enriched in the same tick
|
|
7010
7003
|
// Because the hook runs synchronously, and the breadcrumb is afterwards passed on
|
|
7011
7004
|
// So any async mutations to it will not be reflected in the final breadcrumb
|
|
7012
|
-
enrichFetchBreadcrumb(breadcrumb, hint
|
|
7005
|
+
enrichFetchBreadcrumb(breadcrumb, hint);
|
|
7013
7006
|
|
|
7014
7007
|
// This call should not reject
|
|
7015
7008
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
@@ -7036,138 +7029,25 @@ function _isFetchHint(hint) {
|
|
|
7036
7029
|
return hint && hint.response;
|
|
7037
7030
|
}
|
|
7038
7031
|
|
|
7039
|
-
let _LAST_BREADCRUMB = null;
|
|
7040
|
-
|
|
7041
|
-
function isBreadcrumbWithCategory(breadcrumb) {
|
|
7042
|
-
return !!breadcrumb.category;
|
|
7043
|
-
}
|
|
7044
|
-
|
|
7045
|
-
const handleScopeListener =
|
|
7046
|
-
(replay) =>
|
|
7047
|
-
(scope) => {
|
|
7048
|
-
if (!replay.isEnabled()) {
|
|
7049
|
-
return;
|
|
7050
|
-
}
|
|
7051
|
-
|
|
7052
|
-
const result = handleScope(scope);
|
|
7053
|
-
|
|
7054
|
-
if (!result) {
|
|
7055
|
-
return;
|
|
7056
|
-
}
|
|
7057
|
-
|
|
7058
|
-
addBreadcrumbEvent(replay, result);
|
|
7059
|
-
};
|
|
7060
|
-
|
|
7061
|
-
/**
|
|
7062
|
-
* An event handler to handle scope changes.
|
|
7063
|
-
*/
|
|
7064
|
-
function handleScope(scope) {
|
|
7065
|
-
// TODO (v8): Remove this guard. This was put in place because we introduced
|
|
7066
|
-
// Scope.getLastBreadcrumb mid-v7 which caused incompatibilities with older SDKs.
|
|
7067
|
-
// For now, we'll just return null if the method doesn't exist but we should eventually
|
|
7068
|
-
// get rid of this guard.
|
|
7069
|
-
const newBreadcrumb = scope.getLastBreadcrumb && scope.getLastBreadcrumb();
|
|
7070
|
-
|
|
7071
|
-
// Listener can be called when breadcrumbs have not changed, so we store the
|
|
7072
|
-
// reference to the last crumb and only return a crumb if it has changed
|
|
7073
|
-
if (_LAST_BREADCRUMB === newBreadcrumb || !newBreadcrumb) {
|
|
7074
|
-
return null;
|
|
7075
|
-
}
|
|
7076
|
-
|
|
7077
|
-
_LAST_BREADCRUMB = newBreadcrumb;
|
|
7078
|
-
|
|
7079
|
-
if (
|
|
7080
|
-
!isBreadcrumbWithCategory(newBreadcrumb) ||
|
|
7081
|
-
['fetch', 'xhr', 'sentry.event', 'sentry.transaction'].includes(newBreadcrumb.category) ||
|
|
7082
|
-
newBreadcrumb.category.startsWith('ui.')
|
|
7083
|
-
) {
|
|
7084
|
-
return null;
|
|
7085
|
-
}
|
|
7086
|
-
|
|
7087
|
-
if (newBreadcrumb.category === 'console') {
|
|
7088
|
-
return normalizeConsoleBreadcrumb(newBreadcrumb);
|
|
7089
|
-
}
|
|
7090
|
-
|
|
7091
|
-
return createBreadcrumb(newBreadcrumb);
|
|
7092
|
-
}
|
|
7093
|
-
|
|
7094
|
-
/** exported for tests only */
|
|
7095
|
-
function normalizeConsoleBreadcrumb(
|
|
7096
|
-
breadcrumb,
|
|
7097
|
-
) {
|
|
7098
|
-
const args = breadcrumb.data && breadcrumb.data.arguments;
|
|
7099
|
-
|
|
7100
|
-
if (!Array.isArray(args) || args.length === 0) {
|
|
7101
|
-
return createBreadcrumb(breadcrumb);
|
|
7102
|
-
}
|
|
7103
|
-
|
|
7104
|
-
let isTruncated = false;
|
|
7105
|
-
|
|
7106
|
-
// Avoid giant args captures
|
|
7107
|
-
const normalizedArgs = args.map(arg => {
|
|
7108
|
-
if (!arg) {
|
|
7109
|
-
return arg;
|
|
7110
|
-
}
|
|
7111
|
-
if (typeof arg === 'string') {
|
|
7112
|
-
if (arg.length > CONSOLE_ARG_MAX_SIZE) {
|
|
7113
|
-
isTruncated = true;
|
|
7114
|
-
return `${arg.slice(0, CONSOLE_ARG_MAX_SIZE)}…`;
|
|
7115
|
-
}
|
|
7116
|
-
|
|
7117
|
-
return arg;
|
|
7118
|
-
}
|
|
7119
|
-
if (typeof arg === 'object') {
|
|
7120
|
-
try {
|
|
7121
|
-
const normalizedArg = utils.normalize(arg, 7);
|
|
7122
|
-
const stringified = JSON.stringify(normalizedArg);
|
|
7123
|
-
if (stringified.length > CONSOLE_ARG_MAX_SIZE) {
|
|
7124
|
-
isTruncated = true;
|
|
7125
|
-
// We use the pretty printed JSON string here as a base
|
|
7126
|
-
return `${JSON.stringify(normalizedArg, null, 2).slice(0, CONSOLE_ARG_MAX_SIZE)}…`;
|
|
7127
|
-
}
|
|
7128
|
-
return normalizedArg;
|
|
7129
|
-
} catch (e) {
|
|
7130
|
-
// fall back to default
|
|
7131
|
-
}
|
|
7132
|
-
}
|
|
7133
|
-
|
|
7134
|
-
return arg;
|
|
7135
|
-
});
|
|
7136
|
-
|
|
7137
|
-
return createBreadcrumb({
|
|
7138
|
-
...breadcrumb,
|
|
7139
|
-
data: {
|
|
7140
|
-
...breadcrumb.data,
|
|
7141
|
-
arguments: normalizedArgs,
|
|
7142
|
-
...(isTruncated ? { _meta: { warnings: ['CONSOLE_ARG_TRUNCATED'] } } : {}),
|
|
7143
|
-
},
|
|
7144
|
-
});
|
|
7145
|
-
}
|
|
7146
|
-
|
|
7147
7032
|
/**
|
|
7148
7033
|
* Add global listeners that cannot be removed.
|
|
7149
7034
|
*/
|
|
7150
7035
|
function addGlobalListeners(replay) {
|
|
7151
7036
|
// Listeners from core SDK //
|
|
7152
|
-
const scope = core.getCurrentScope();
|
|
7153
7037
|
const client = core.getClient();
|
|
7154
7038
|
|
|
7155
|
-
scope.addScopeListener(handleScopeListener(replay));
|
|
7156
7039
|
utils.addClickKeypressInstrumentationHandler(handleDomListener(replay));
|
|
7157
7040
|
utils.addHistoryInstrumentationHandler(handleHistorySpanListener(replay));
|
|
7041
|
+
handleBreadcrumbs(replay);
|
|
7158
7042
|
handleNetworkBreadcrumbs(replay);
|
|
7159
7043
|
|
|
7160
7044
|
// Tag all (non replay) events that get sent to Sentry with the current
|
|
7161
7045
|
// replay ID so that we can reference them later in the UI
|
|
7162
|
-
const eventProcessor = handleGlobalEventListener(replay
|
|
7163
|
-
|
|
7164
|
-
client.addEventProcessor(eventProcessor);
|
|
7165
|
-
} else {
|
|
7166
|
-
core.addEventProcessor(eventProcessor);
|
|
7167
|
-
}
|
|
7046
|
+
const eventProcessor = handleGlobalEventListener(replay);
|
|
7047
|
+
core.addEventProcessor(eventProcessor);
|
|
7168
7048
|
|
|
7169
7049
|
// If a custom client has no hooks yet, we continue to use the "old" implementation
|
|
7170
|
-
if (
|
|
7050
|
+
if (client) {
|
|
7171
7051
|
client.on('beforeSendEvent', handleBeforeSendEvent(replay));
|
|
7172
7052
|
client.on('afterSendEvent', handleAfterSendEvent(replay));
|
|
7173
7053
|
client.on('createDsc', (dsc) => {
|
|
@@ -7205,11 +7085,6 @@ function addGlobalListeners(replay) {
|
|
|
7205
7085
|
}
|
|
7206
7086
|
}
|
|
7207
7087
|
|
|
7208
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
7209
|
-
function hasHooks(client) {
|
|
7210
|
-
return !!(client && client.on);
|
|
7211
|
-
}
|
|
7212
|
-
|
|
7213
7088
|
/**
|
|
7214
7089
|
* Create a "span" for the total amount of memory being used by JS objects
|
|
7215
7090
|
* (including v8 internal objects).
|
|
@@ -7531,9 +7406,7 @@ async function prepareReplayEvent({
|
|
|
7531
7406
|
|
|
7532
7407
|
const eventHint = { event_id, integrations };
|
|
7533
7408
|
|
|
7534
|
-
|
|
7535
|
-
client.emit('preprocessEvent', event, eventHint);
|
|
7536
|
-
}
|
|
7409
|
+
client.emit('preprocessEvent', event, eventHint);
|
|
7537
7410
|
|
|
7538
7411
|
const preparedEvent = (await core.prepareEvent(
|
|
7539
7412
|
client.getOptions(),
|
|
@@ -7555,7 +7428,7 @@ async function prepareReplayEvent({
|
|
|
7555
7428
|
preparedEvent.platform = preparedEvent.platform || 'javascript';
|
|
7556
7429
|
|
|
7557
7430
|
// extract the SDK name because `client._prepareEvent` doesn't add it to the event
|
|
7558
|
-
const metadata = client.getSdkMetadata
|
|
7431
|
+
const metadata = client.getSdkMetadata();
|
|
7559
7432
|
const { name, version } = (metadata && metadata.sdk) || {};
|
|
7560
7433
|
|
|
7561
7434
|
preparedEvent.sdk = {
|
|
@@ -9539,12 +9412,9 @@ function _getMergedNetworkHeaders(headers) {
|
|
|
9539
9412
|
/**
|
|
9540
9413
|
* This is a small utility to get a type-safe instance of the Replay integration.
|
|
9541
9414
|
*/
|
|
9542
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
9543
9415
|
function getReplay() {
|
|
9544
9416
|
const client = core.getClient();
|
|
9545
|
-
return (
|
|
9546
|
-
client && client.getIntegrationByName && client.getIntegrationByName('Replay')
|
|
9547
|
-
);
|
|
9417
|
+
return client && client.getIntegrationByName('Replay');
|
|
9548
9418
|
}
|
|
9549
9419
|
|
|
9550
9420
|
exports.Replay = Replay;
|