@sentry/replay 7.105.0 → 8.0.0-alpha.2
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 +131 -286
- package/cjs/index.js.map +1 -1
- package/esm/index.js +133 -288
- package/esm/index.js.map +1 -1
- package/package.json +7 -7
- package/types/coreHandlers/handleAfterSendEvent.d.ts +1 -1
- package/types/coreHandlers/handleAfterSendEvent.d.ts.map +1 -1
- 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/util/sendReplayRequest.d.ts +1 -1
- package/types/util/sendReplayRequest.d.ts.map +1 -1
- package/types-ts3.8/coreHandlers/handleAfterSendEvent.d.ts +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-ts3.8/util/sendReplayRequest.d.ts +1 -1
- 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
|
@@ -5714,10 +5714,6 @@ function isFeedbackEvent(event) {
|
|
|
5714
5714
|
* Returns a listener to be added to `client.on('afterSendErrorEvent, listener)`.
|
|
5715
5715
|
*/
|
|
5716
5716
|
function handleAfterSendEvent(replay) {
|
|
5717
|
-
// Custom transports may still be returning `Promise<void>`, which means we cannot expect the status code to be available there
|
|
5718
|
-
// TODO (v8): remove this check as it will no longer be necessary
|
|
5719
|
-
const enforceStatusCode = isBaseTransportSend();
|
|
5720
|
-
|
|
5721
5717
|
return (event, sendResponse) => {
|
|
5722
5718
|
if (!replay.isEnabled() || (!isErrorEvent(event) && !isTransactionEvent(event))) {
|
|
5723
5719
|
return;
|
|
@@ -5728,7 +5724,7 @@ function handleAfterSendEvent(replay) {
|
|
|
5728
5724
|
// We only want to do stuff on successful error sending, otherwise you get error replays without errors attached
|
|
5729
5725
|
// If not using the base transport, we allow `undefined` response (as a custom transport may not implement this correctly yet)
|
|
5730
5726
|
// If we do use the base transport, we skip if we encountered an non-OK status code
|
|
5731
|
-
if (
|
|
5727
|
+
if (!statusCode || statusCode < 200 || statusCode >= 300) {
|
|
5732
5728
|
return;
|
|
5733
5729
|
}
|
|
5734
5730
|
|
|
@@ -5784,22 +5780,6 @@ function handleErrorEvent(replay, event) {
|
|
|
5784
5780
|
});
|
|
5785
5781
|
}
|
|
5786
5782
|
|
|
5787
|
-
function isBaseTransportSend() {
|
|
5788
|
-
const client = core.getClient();
|
|
5789
|
-
if (!client) {
|
|
5790
|
-
return false;
|
|
5791
|
-
}
|
|
5792
|
-
|
|
5793
|
-
const transport = client.getTransport();
|
|
5794
|
-
if (!transport) {
|
|
5795
|
-
return false;
|
|
5796
|
-
}
|
|
5797
|
-
|
|
5798
|
-
return (
|
|
5799
|
-
(transport.send ).__sentry__baseTransport__ || false
|
|
5800
|
-
);
|
|
5801
|
-
}
|
|
5802
|
-
|
|
5803
5783
|
/**
|
|
5804
5784
|
* Returns a listener to be added to `client.on('afterSendErrorEvent, listener)`.
|
|
5805
5785
|
*/
|
|
@@ -5835,6 +5815,112 @@ function handleHydrationError(replay, event) {
|
|
|
5835
5815
|
}
|
|
5836
5816
|
}
|
|
5837
5817
|
|
|
5818
|
+
/**
|
|
5819
|
+
* Handle breadcrumbs that Sentry captures, and make sure to capture relevant breadcrumbs to Replay as well.
|
|
5820
|
+
*/
|
|
5821
|
+
function handleBreadcrumbs(replay) {
|
|
5822
|
+
const client = core.getClient();
|
|
5823
|
+
|
|
5824
|
+
if (!client) {
|
|
5825
|
+
return;
|
|
5826
|
+
}
|
|
5827
|
+
|
|
5828
|
+
client.on('beforeAddBreadcrumb', breadcrumb => beforeAddBreadcrumb(replay, breadcrumb));
|
|
5829
|
+
}
|
|
5830
|
+
|
|
5831
|
+
function beforeAddBreadcrumb(replay, breadcrumb) {
|
|
5832
|
+
if (!replay.isEnabled() || !isBreadcrumbWithCategory(breadcrumb)) {
|
|
5833
|
+
return;
|
|
5834
|
+
}
|
|
5835
|
+
|
|
5836
|
+
const result = normalizeBreadcrumb(breadcrumb);
|
|
5837
|
+
if (result) {
|
|
5838
|
+
addBreadcrumbEvent(replay, result);
|
|
5839
|
+
}
|
|
5840
|
+
}
|
|
5841
|
+
|
|
5842
|
+
/** Exported only for tests. */
|
|
5843
|
+
function normalizeBreadcrumb(breadcrumb) {
|
|
5844
|
+
if (
|
|
5845
|
+
!isBreadcrumbWithCategory(breadcrumb) ||
|
|
5846
|
+
[
|
|
5847
|
+
// fetch & xhr are handled separately,in handleNetworkBreadcrumbs
|
|
5848
|
+
'fetch',
|
|
5849
|
+
'xhr',
|
|
5850
|
+
// These two are breadcrumbs for emitted sentry events, we don't care about them
|
|
5851
|
+
'sentry.event',
|
|
5852
|
+
'sentry.transaction',
|
|
5853
|
+
].includes(breadcrumb.category) ||
|
|
5854
|
+
// We capture UI breadcrumbs separately
|
|
5855
|
+
breadcrumb.category.startsWith('ui.')
|
|
5856
|
+
) {
|
|
5857
|
+
return null;
|
|
5858
|
+
}
|
|
5859
|
+
|
|
5860
|
+
if (breadcrumb.category === 'console') {
|
|
5861
|
+
return normalizeConsoleBreadcrumb(breadcrumb);
|
|
5862
|
+
}
|
|
5863
|
+
|
|
5864
|
+
return createBreadcrumb(breadcrumb);
|
|
5865
|
+
}
|
|
5866
|
+
|
|
5867
|
+
/** exported for tests only */
|
|
5868
|
+
function normalizeConsoleBreadcrumb(
|
|
5869
|
+
breadcrumb,
|
|
5870
|
+
) {
|
|
5871
|
+
const args = breadcrumb.data && breadcrumb.data.arguments;
|
|
5872
|
+
|
|
5873
|
+
if (!Array.isArray(args) || args.length === 0) {
|
|
5874
|
+
return createBreadcrumb(breadcrumb);
|
|
5875
|
+
}
|
|
5876
|
+
|
|
5877
|
+
let isTruncated = false;
|
|
5878
|
+
|
|
5879
|
+
// Avoid giant args captures
|
|
5880
|
+
const normalizedArgs = args.map(arg => {
|
|
5881
|
+
if (!arg) {
|
|
5882
|
+
return arg;
|
|
5883
|
+
}
|
|
5884
|
+
if (typeof arg === 'string') {
|
|
5885
|
+
if (arg.length > CONSOLE_ARG_MAX_SIZE) {
|
|
5886
|
+
isTruncated = true;
|
|
5887
|
+
return `${arg.slice(0, CONSOLE_ARG_MAX_SIZE)}…`;
|
|
5888
|
+
}
|
|
5889
|
+
|
|
5890
|
+
return arg;
|
|
5891
|
+
}
|
|
5892
|
+
if (typeof arg === 'object') {
|
|
5893
|
+
try {
|
|
5894
|
+
const normalizedArg = utils.normalize(arg, 7);
|
|
5895
|
+
const stringified = JSON.stringify(normalizedArg);
|
|
5896
|
+
if (stringified.length > CONSOLE_ARG_MAX_SIZE) {
|
|
5897
|
+
isTruncated = true;
|
|
5898
|
+
// We use the pretty printed JSON string here as a base
|
|
5899
|
+
return `${JSON.stringify(normalizedArg, null, 2).slice(0, CONSOLE_ARG_MAX_SIZE)}…`;
|
|
5900
|
+
}
|
|
5901
|
+
return normalizedArg;
|
|
5902
|
+
} catch (e) {
|
|
5903
|
+
// fall back to default
|
|
5904
|
+
}
|
|
5905
|
+
}
|
|
5906
|
+
|
|
5907
|
+
return arg;
|
|
5908
|
+
});
|
|
5909
|
+
|
|
5910
|
+
return createBreadcrumb({
|
|
5911
|
+
...breadcrumb,
|
|
5912
|
+
data: {
|
|
5913
|
+
...breadcrumb.data,
|
|
5914
|
+
arguments: normalizedArgs,
|
|
5915
|
+
...(isTruncated ? { _meta: { warnings: ['CONSOLE_ARG_TRUNCATED'] } } : {}),
|
|
5916
|
+
},
|
|
5917
|
+
});
|
|
5918
|
+
}
|
|
5919
|
+
|
|
5920
|
+
function isBreadcrumbWithCategory(breadcrumb) {
|
|
5921
|
+
return !!breadcrumb.category;
|
|
5922
|
+
}
|
|
5923
|
+
|
|
5838
5924
|
/**
|
|
5839
5925
|
* Returns true if we think the given event is an error originating inside of rrweb.
|
|
5840
5926
|
*/
|
|
@@ -5912,12 +5998,7 @@ function shouldSampleForBufferEvent(replay, event) {
|
|
|
5912
5998
|
/**
|
|
5913
5999
|
* Returns a listener to be added to `addEventProcessor(listener)`.
|
|
5914
6000
|
*/
|
|
5915
|
-
function handleGlobalEventListener(
|
|
5916
|
-
replay,
|
|
5917
|
-
includeAfterSendEventHandling = false,
|
|
5918
|
-
) {
|
|
5919
|
-
const afterSendHandler = includeAfterSendEventHandling ? handleAfterSendEvent(replay) : undefined;
|
|
5920
|
-
|
|
6001
|
+
function handleGlobalEventListener(replay) {
|
|
5921
6002
|
return Object.assign(
|
|
5922
6003
|
(event, hint) => {
|
|
5923
6004
|
// Do nothing if replay has been disabled
|
|
@@ -5973,13 +6054,6 @@ function handleGlobalEventListener(
|
|
|
5973
6054
|
event.tags = { ...event.tags, replayId: replay.getSessionId() };
|
|
5974
6055
|
}
|
|
5975
6056
|
|
|
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
6057
|
return event;
|
|
5984
6058
|
},
|
|
5985
6059
|
{ id: 'Replay' },
|
|
@@ -6096,97 +6170,14 @@ function addNetworkBreadcrumb(
|
|
|
6096
6170
|
});
|
|
6097
6171
|
}
|
|
6098
6172
|
|
|
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
6173
|
/** Get the size of a body. */
|
|
6182
|
-
function getBodySize(
|
|
6183
|
-
body,
|
|
6184
|
-
textEncoder,
|
|
6185
|
-
) {
|
|
6174
|
+
function getBodySize(body) {
|
|
6186
6175
|
if (!body) {
|
|
6187
6176
|
return undefined;
|
|
6188
6177
|
}
|
|
6189
6178
|
|
|
6179
|
+
const textEncoder = new TextEncoder();
|
|
6180
|
+
|
|
6190
6181
|
try {
|
|
6191
6182
|
if (typeof body === 'string') {
|
|
6192
6183
|
return textEncoder.encode(body).length;
|
|
@@ -6486,12 +6477,11 @@ async function captureFetchBreadcrumbToReplay(
|
|
|
6486
6477
|
function enrichFetchBreadcrumb(
|
|
6487
6478
|
breadcrumb,
|
|
6488
6479
|
hint,
|
|
6489
|
-
options,
|
|
6490
6480
|
) {
|
|
6491
6481
|
const { input, response } = hint;
|
|
6492
6482
|
|
|
6493
6483
|
const body = input ? _getFetchRequestArgBody(input) : undefined;
|
|
6494
|
-
const reqSize = getBodySize(body
|
|
6484
|
+
const reqSize = getBodySize(body);
|
|
6495
6485
|
|
|
6496
6486
|
const resSize = response ? parseContentLengthHeader(response.headers.get('content-length')) : undefined;
|
|
6497
6487
|
|
|
@@ -6506,9 +6496,7 @@ function enrichFetchBreadcrumb(
|
|
|
6506
6496
|
async function _prepareFetchData(
|
|
6507
6497
|
breadcrumb,
|
|
6508
6498
|
hint,
|
|
6509
|
-
options
|
|
6510
|
-
|
|
6511
|
-
,
|
|
6499
|
+
options,
|
|
6512
6500
|
) {
|
|
6513
6501
|
const now = Date.now();
|
|
6514
6502
|
const { startTimestamp = now, endTimestamp = now } = hint;
|
|
@@ -6568,11 +6556,8 @@ async function _getResponseInfo(
|
|
|
6568
6556
|
captureDetails,
|
|
6569
6557
|
{
|
|
6570
6558
|
networkCaptureBodies,
|
|
6571
|
-
textEncoder,
|
|
6572
6559
|
networkResponseHeaders,
|
|
6573
|
-
}
|
|
6574
|
-
|
|
6575
|
-
,
|
|
6560
|
+
},
|
|
6576
6561
|
response,
|
|
6577
6562
|
responseBodySize,
|
|
6578
6563
|
) {
|
|
@@ -6589,7 +6574,7 @@ async function _getResponseInfo(
|
|
|
6589
6574
|
const [bodyText, warning] = await _parseFetchResponseBody(response);
|
|
6590
6575
|
const result = getResponseData(bodyText, {
|
|
6591
6576
|
networkCaptureBodies,
|
|
6592
|
-
|
|
6577
|
+
|
|
6593
6578
|
responseBodySize,
|
|
6594
6579
|
captureDetails,
|
|
6595
6580
|
headers,
|
|
@@ -6606,7 +6591,6 @@ function getResponseData(
|
|
|
6606
6591
|
bodyText,
|
|
6607
6592
|
{
|
|
6608
6593
|
networkCaptureBodies,
|
|
6609
|
-
textEncoder,
|
|
6610
6594
|
responseBodySize,
|
|
6611
6595
|
captureDetails,
|
|
6612
6596
|
headers,
|
|
@@ -6616,9 +6600,7 @@ function getResponseData(
|
|
|
6616
6600
|
) {
|
|
6617
6601
|
try {
|
|
6618
6602
|
const size =
|
|
6619
|
-
bodyText && bodyText.length && responseBodySize === undefined
|
|
6620
|
-
? getBodySize(bodyText, textEncoder)
|
|
6621
|
-
: responseBodySize;
|
|
6603
|
+
bodyText && bodyText.length && responseBodySize === undefined ? getBodySize(bodyText) : responseBodySize;
|
|
6622
6604
|
|
|
6623
6605
|
if (!captureDetails) {
|
|
6624
6606
|
return buildSkippedNetworkRequestOrResponse(size);
|
|
@@ -6773,7 +6755,6 @@ async function captureXhrBreadcrumbToReplay(
|
|
|
6773
6755
|
function enrichXhrBreadcrumb(
|
|
6774
6756
|
breadcrumb,
|
|
6775
6757
|
hint,
|
|
6776
|
-
options,
|
|
6777
6758
|
) {
|
|
6778
6759
|
const { xhr, input } = hint;
|
|
6779
6760
|
|
|
@@ -6781,10 +6762,10 @@ function enrichXhrBreadcrumb(
|
|
|
6781
6762
|
return;
|
|
6782
6763
|
}
|
|
6783
6764
|
|
|
6784
|
-
const reqSize = getBodySize(input
|
|
6765
|
+
const reqSize = getBodySize(input);
|
|
6785
6766
|
const resSize = xhr.getResponseHeader('content-length')
|
|
6786
6767
|
? parseContentLengthHeader(xhr.getResponseHeader('content-length'))
|
|
6787
|
-
: _getBodySize(xhr.response, xhr.responseType
|
|
6768
|
+
: _getBodySize(xhr.response, xhr.responseType);
|
|
6788
6769
|
|
|
6789
6770
|
if (reqSize !== undefined) {
|
|
6790
6771
|
breadcrumb.data.request_body_size = reqSize;
|
|
@@ -6931,11 +6912,10 @@ function _parseXhrResponse(
|
|
|
6931
6912
|
function _getBodySize(
|
|
6932
6913
|
body,
|
|
6933
6914
|
responseType,
|
|
6934
|
-
textEncoder,
|
|
6935
6915
|
) {
|
|
6936
6916
|
try {
|
|
6937
6917
|
const bodyStr = responseType === 'json' && body && typeof body === 'object' ? JSON.stringify(body) : body;
|
|
6938
|
-
return getBodySize(bodyStr
|
|
6918
|
+
return getBodySize(bodyStr);
|
|
6939
6919
|
} catch (e3) {
|
|
6940
6920
|
return undefined;
|
|
6941
6921
|
}
|
|
@@ -6951,8 +6931,6 @@ function handleNetworkBreadcrumbs(replay) {
|
|
|
6951
6931
|
const client = core.getClient();
|
|
6952
6932
|
|
|
6953
6933
|
try {
|
|
6954
|
-
const textEncoder = new TextEncoder();
|
|
6955
|
-
|
|
6956
6934
|
const {
|
|
6957
6935
|
networkDetailAllowUrls,
|
|
6958
6936
|
networkDetailDenyUrls,
|
|
@@ -6963,7 +6941,6 @@ function handleNetworkBreadcrumbs(replay) {
|
|
|
6963
6941
|
|
|
6964
6942
|
const options = {
|
|
6965
6943
|
replay,
|
|
6966
|
-
textEncoder,
|
|
6967
6944
|
networkDetailAllowUrls,
|
|
6968
6945
|
networkDetailDenyUrls,
|
|
6969
6946
|
networkCaptureBodies,
|
|
@@ -6971,12 +6948,8 @@ function handleNetworkBreadcrumbs(replay) {
|
|
|
6971
6948
|
networkResponseHeaders,
|
|
6972
6949
|
};
|
|
6973
6950
|
|
|
6974
|
-
if (client
|
|
6951
|
+
if (client) {
|
|
6975
6952
|
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
6953
|
}
|
|
6981
6954
|
} catch (e2) {
|
|
6982
6955
|
// Do nothing
|
|
@@ -6998,7 +6971,7 @@ function beforeAddNetworkBreadcrumb(
|
|
|
6998
6971
|
// This has to be sync, as we need to ensure the breadcrumb is enriched in the same tick
|
|
6999
6972
|
// Because the hook runs synchronously, and the breadcrumb is afterwards passed on
|
|
7000
6973
|
// So any async mutations to it will not be reflected in the final breadcrumb
|
|
7001
|
-
enrichXhrBreadcrumb(breadcrumb, hint
|
|
6974
|
+
enrichXhrBreadcrumb(breadcrumb, hint);
|
|
7002
6975
|
|
|
7003
6976
|
// This call should not reject
|
|
7004
6977
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
@@ -7009,7 +6982,7 @@ function beforeAddNetworkBreadcrumb(
|
|
|
7009
6982
|
// This has to be sync, as we need to ensure the breadcrumb is enriched in the same tick
|
|
7010
6983
|
// Because the hook runs synchronously, and the breadcrumb is afterwards passed on
|
|
7011
6984
|
// So any async mutations to it will not be reflected in the final breadcrumb
|
|
7012
|
-
enrichFetchBreadcrumb(breadcrumb, hint
|
|
6985
|
+
enrichFetchBreadcrumb(breadcrumb, hint);
|
|
7013
6986
|
|
|
7014
6987
|
// This call should not reject
|
|
7015
6988
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
@@ -7036,138 +7009,25 @@ function _isFetchHint(hint) {
|
|
|
7036
7009
|
return hint && hint.response;
|
|
7037
7010
|
}
|
|
7038
7011
|
|
|
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
7012
|
/**
|
|
7148
7013
|
* Add global listeners that cannot be removed.
|
|
7149
7014
|
*/
|
|
7150
7015
|
function addGlobalListeners(replay) {
|
|
7151
7016
|
// Listeners from core SDK //
|
|
7152
|
-
const scope = core.getCurrentScope();
|
|
7153
7017
|
const client = core.getClient();
|
|
7154
7018
|
|
|
7155
|
-
scope.addScopeListener(handleScopeListener(replay));
|
|
7156
7019
|
utils.addClickKeypressInstrumentationHandler(handleDomListener(replay));
|
|
7157
7020
|
utils.addHistoryInstrumentationHandler(handleHistorySpanListener(replay));
|
|
7021
|
+
handleBreadcrumbs(replay);
|
|
7158
7022
|
handleNetworkBreadcrumbs(replay);
|
|
7159
7023
|
|
|
7160
7024
|
// Tag all (non replay) events that get sent to Sentry with the current
|
|
7161
7025
|
// 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
|
-
}
|
|
7026
|
+
const eventProcessor = handleGlobalEventListener(replay);
|
|
7027
|
+
core.addEventProcessor(eventProcessor);
|
|
7168
7028
|
|
|
7169
7029
|
// If a custom client has no hooks yet, we continue to use the "old" implementation
|
|
7170
|
-
if (
|
|
7030
|
+
if (client) {
|
|
7171
7031
|
client.on('beforeSendEvent', handleBeforeSendEvent(replay));
|
|
7172
7032
|
client.on('afterSendEvent', handleAfterSendEvent(replay));
|
|
7173
7033
|
client.on('createDsc', (dsc) => {
|
|
@@ -7205,11 +7065,6 @@ function addGlobalListeners(replay) {
|
|
|
7205
7065
|
}
|
|
7206
7066
|
}
|
|
7207
7067
|
|
|
7208
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
7209
|
-
function hasHooks(client) {
|
|
7210
|
-
return !!(client && client.on);
|
|
7211
|
-
}
|
|
7212
|
-
|
|
7213
7068
|
/**
|
|
7214
7069
|
* Create a "span" for the total amount of memory being used by JS objects
|
|
7215
7070
|
* (including v8 internal objects).
|
|
@@ -7531,9 +7386,7 @@ async function prepareReplayEvent({
|
|
|
7531
7386
|
|
|
7532
7387
|
const eventHint = { event_id, integrations };
|
|
7533
7388
|
|
|
7534
|
-
|
|
7535
|
-
client.emit('preprocessEvent', event, eventHint);
|
|
7536
|
-
}
|
|
7389
|
+
client.emit('preprocessEvent', event, eventHint);
|
|
7537
7390
|
|
|
7538
7391
|
const preparedEvent = (await core.prepareEvent(
|
|
7539
7392
|
client.getOptions(),
|
|
@@ -7555,7 +7408,7 @@ async function prepareReplayEvent({
|
|
|
7555
7408
|
preparedEvent.platform = preparedEvent.platform || 'javascript';
|
|
7556
7409
|
|
|
7557
7410
|
// extract the SDK name because `client._prepareEvent` doesn't add it to the event
|
|
7558
|
-
const metadata = client.getSdkMetadata
|
|
7411
|
+
const metadata = client.getSdkMetadata();
|
|
7559
7412
|
const { name, version } = (metadata && metadata.sdk) || {};
|
|
7560
7413
|
|
|
7561
7414
|
preparedEvent.sdk = {
|
|
@@ -7593,7 +7446,7 @@ async function sendReplayRequest({
|
|
|
7593
7446
|
const dsn = client && client.getDsn();
|
|
7594
7447
|
|
|
7595
7448
|
if (!client || !transport || !dsn || !session.sampled) {
|
|
7596
|
-
return;
|
|
7449
|
+
return utils.resolvedSyncPromise({});
|
|
7597
7450
|
}
|
|
7598
7451
|
|
|
7599
7452
|
const baseEvent = {
|
|
@@ -7614,7 +7467,7 @@ async function sendReplayRequest({
|
|
|
7614
7467
|
// Taken from baseclient's `_processEvent` method, where this is handled for errors/transactions
|
|
7615
7468
|
client.recordDroppedEvent('event_processor', 'replay', baseEvent);
|
|
7616
7469
|
logInfo('An event processor returned `null`, will not send event.');
|
|
7617
|
-
return;
|
|
7470
|
+
return utils.resolvedSyncPromise({});
|
|
7618
7471
|
}
|
|
7619
7472
|
|
|
7620
7473
|
/*
|
|
@@ -7676,11 +7529,6 @@ async function sendReplayRequest({
|
|
|
7676
7529
|
throw error;
|
|
7677
7530
|
}
|
|
7678
7531
|
|
|
7679
|
-
// TODO (v8): we can remove this guard once transport.send's type signature doesn't include void anymore
|
|
7680
|
-
if (!response) {
|
|
7681
|
-
return response;
|
|
7682
|
-
}
|
|
7683
|
-
|
|
7684
7532
|
// If the status code is invalid, we want to immediately stop & not retry
|
|
7685
7533
|
if (typeof response.statusCode === 'number' && (response.statusCode < 200 || response.statusCode >= 300)) {
|
|
7686
7534
|
throw new TransportStatusCodeError(response.statusCode);
|
|
@@ -9539,12 +9387,9 @@ function _getMergedNetworkHeaders(headers) {
|
|
|
9539
9387
|
/**
|
|
9540
9388
|
* This is a small utility to get a type-safe instance of the Replay integration.
|
|
9541
9389
|
*/
|
|
9542
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
9543
9390
|
function getReplay() {
|
|
9544
9391
|
const client = core.getClient();
|
|
9545
|
-
return (
|
|
9546
|
-
client && client.getIntegrationByName && client.getIntegrationByName('Replay')
|
|
9547
|
-
);
|
|
9392
|
+
return client && client.getIntegrationByName('Replay');
|
|
9548
9393
|
}
|
|
9549
9394
|
|
|
9550
9395
|
exports.Replay = Replay;
|