@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/esm/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { _nullishCoalesce, _optionalChain } from '@sentry/utils';
|
|
2
|
-
import { addBreadcrumb, getClient, isSentryRequestUrl,
|
|
3
|
-
import { GLOBAL_OBJ, normalize, fill, htmlTreeAsString, browserPerformanceTimeOrigin, logger, uuid4,
|
|
2
|
+
import { addBreadcrumb, getClient, isSentryRequestUrl, addEventProcessor, prepareEvent, getIsolationScope, getCurrentScope, setContext, captureException, spanToJSON, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/core';
|
|
3
|
+
import { GLOBAL_OBJ, normalize, fill, htmlTreeAsString, browserPerformanceTimeOrigin, logger, uuid4, dropUndefinedKeys, stringMatchesSomePattern, SENTRY_XHR_DATA_KEY, addClickKeypressInstrumentationHandler, addHistoryInstrumentationHandler, createEnvelope, createEventEnvelopeHeaders, getSdkMetadataForEnvelopeHeader, resolvedSyncPromise, updateRateLimits, isRateLimited, consoleSandbox, isBrowser } from '@sentry/utils';
|
|
4
4
|
import { addPerformanceInstrumentationHandler, addLcpInstrumentationHandler } from '@sentry-internal/tracing';
|
|
5
5
|
|
|
6
6
|
// exporting a separate copy of `WINDOW` rather than exporting the one from `@sentry/browser`
|
|
@@ -5708,10 +5708,6 @@ function isFeedbackEvent(event) {
|
|
|
5708
5708
|
* Returns a listener to be added to `client.on('afterSendErrorEvent, listener)`.
|
|
5709
5709
|
*/
|
|
5710
5710
|
function handleAfterSendEvent(replay) {
|
|
5711
|
-
// Custom transports may still be returning `Promise<void>`, which means we cannot expect the status code to be available there
|
|
5712
|
-
// TODO (v8): remove this check as it will no longer be necessary
|
|
5713
|
-
const enforceStatusCode = isBaseTransportSend();
|
|
5714
|
-
|
|
5715
5711
|
return (event, sendResponse) => {
|
|
5716
5712
|
if (!replay.isEnabled() || (!isErrorEvent(event) && !isTransactionEvent(event))) {
|
|
5717
5713
|
return;
|
|
@@ -5722,7 +5718,7 @@ function handleAfterSendEvent(replay) {
|
|
|
5722
5718
|
// We only want to do stuff on successful error sending, otherwise you get error replays without errors attached
|
|
5723
5719
|
// If not using the base transport, we allow `undefined` response (as a custom transport may not implement this correctly yet)
|
|
5724
5720
|
// If we do use the base transport, we skip if we encountered an non-OK status code
|
|
5725
|
-
if (
|
|
5721
|
+
if (!statusCode || statusCode < 200 || statusCode >= 300) {
|
|
5726
5722
|
return;
|
|
5727
5723
|
}
|
|
5728
5724
|
|
|
@@ -5778,22 +5774,6 @@ function handleErrorEvent(replay, event) {
|
|
|
5778
5774
|
});
|
|
5779
5775
|
}
|
|
5780
5776
|
|
|
5781
|
-
function isBaseTransportSend() {
|
|
5782
|
-
const client = getClient();
|
|
5783
|
-
if (!client) {
|
|
5784
|
-
return false;
|
|
5785
|
-
}
|
|
5786
|
-
|
|
5787
|
-
const transport = client.getTransport();
|
|
5788
|
-
if (!transport) {
|
|
5789
|
-
return false;
|
|
5790
|
-
}
|
|
5791
|
-
|
|
5792
|
-
return (
|
|
5793
|
-
(transport.send ).__sentry__baseTransport__ || false
|
|
5794
|
-
);
|
|
5795
|
-
}
|
|
5796
|
-
|
|
5797
5777
|
/**
|
|
5798
5778
|
* Returns a listener to be added to `client.on('afterSendErrorEvent, listener)`.
|
|
5799
5779
|
*/
|
|
@@ -5829,6 +5809,112 @@ function handleHydrationError(replay, event) {
|
|
|
5829
5809
|
}
|
|
5830
5810
|
}
|
|
5831
5811
|
|
|
5812
|
+
/**
|
|
5813
|
+
* Handle breadcrumbs that Sentry captures, and make sure to capture relevant breadcrumbs to Replay as well.
|
|
5814
|
+
*/
|
|
5815
|
+
function handleBreadcrumbs(replay) {
|
|
5816
|
+
const client = getClient();
|
|
5817
|
+
|
|
5818
|
+
if (!client) {
|
|
5819
|
+
return;
|
|
5820
|
+
}
|
|
5821
|
+
|
|
5822
|
+
client.on('beforeAddBreadcrumb', breadcrumb => beforeAddBreadcrumb(replay, breadcrumb));
|
|
5823
|
+
}
|
|
5824
|
+
|
|
5825
|
+
function beforeAddBreadcrumb(replay, breadcrumb) {
|
|
5826
|
+
if (!replay.isEnabled() || !isBreadcrumbWithCategory(breadcrumb)) {
|
|
5827
|
+
return;
|
|
5828
|
+
}
|
|
5829
|
+
|
|
5830
|
+
const result = normalizeBreadcrumb(breadcrumb);
|
|
5831
|
+
if (result) {
|
|
5832
|
+
addBreadcrumbEvent(replay, result);
|
|
5833
|
+
}
|
|
5834
|
+
}
|
|
5835
|
+
|
|
5836
|
+
/** Exported only for tests. */
|
|
5837
|
+
function normalizeBreadcrumb(breadcrumb) {
|
|
5838
|
+
if (
|
|
5839
|
+
!isBreadcrumbWithCategory(breadcrumb) ||
|
|
5840
|
+
[
|
|
5841
|
+
// fetch & xhr are handled separately,in handleNetworkBreadcrumbs
|
|
5842
|
+
'fetch',
|
|
5843
|
+
'xhr',
|
|
5844
|
+
// These two are breadcrumbs for emitted sentry events, we don't care about them
|
|
5845
|
+
'sentry.event',
|
|
5846
|
+
'sentry.transaction',
|
|
5847
|
+
].includes(breadcrumb.category) ||
|
|
5848
|
+
// We capture UI breadcrumbs separately
|
|
5849
|
+
breadcrumb.category.startsWith('ui.')
|
|
5850
|
+
) {
|
|
5851
|
+
return null;
|
|
5852
|
+
}
|
|
5853
|
+
|
|
5854
|
+
if (breadcrumb.category === 'console') {
|
|
5855
|
+
return normalizeConsoleBreadcrumb(breadcrumb);
|
|
5856
|
+
}
|
|
5857
|
+
|
|
5858
|
+
return createBreadcrumb(breadcrumb);
|
|
5859
|
+
}
|
|
5860
|
+
|
|
5861
|
+
/** exported for tests only */
|
|
5862
|
+
function normalizeConsoleBreadcrumb(
|
|
5863
|
+
breadcrumb,
|
|
5864
|
+
) {
|
|
5865
|
+
const args = breadcrumb.data && breadcrumb.data.arguments;
|
|
5866
|
+
|
|
5867
|
+
if (!Array.isArray(args) || args.length === 0) {
|
|
5868
|
+
return createBreadcrumb(breadcrumb);
|
|
5869
|
+
}
|
|
5870
|
+
|
|
5871
|
+
let isTruncated = false;
|
|
5872
|
+
|
|
5873
|
+
// Avoid giant args captures
|
|
5874
|
+
const normalizedArgs = args.map(arg => {
|
|
5875
|
+
if (!arg) {
|
|
5876
|
+
return arg;
|
|
5877
|
+
}
|
|
5878
|
+
if (typeof arg === 'string') {
|
|
5879
|
+
if (arg.length > CONSOLE_ARG_MAX_SIZE) {
|
|
5880
|
+
isTruncated = true;
|
|
5881
|
+
return `${arg.slice(0, CONSOLE_ARG_MAX_SIZE)}…`;
|
|
5882
|
+
}
|
|
5883
|
+
|
|
5884
|
+
return arg;
|
|
5885
|
+
}
|
|
5886
|
+
if (typeof arg === 'object') {
|
|
5887
|
+
try {
|
|
5888
|
+
const normalizedArg = normalize(arg, 7);
|
|
5889
|
+
const stringified = JSON.stringify(normalizedArg);
|
|
5890
|
+
if (stringified.length > CONSOLE_ARG_MAX_SIZE) {
|
|
5891
|
+
isTruncated = true;
|
|
5892
|
+
// We use the pretty printed JSON string here as a base
|
|
5893
|
+
return `${JSON.stringify(normalizedArg, null, 2).slice(0, CONSOLE_ARG_MAX_SIZE)}…`;
|
|
5894
|
+
}
|
|
5895
|
+
return normalizedArg;
|
|
5896
|
+
} catch (e) {
|
|
5897
|
+
// fall back to default
|
|
5898
|
+
}
|
|
5899
|
+
}
|
|
5900
|
+
|
|
5901
|
+
return arg;
|
|
5902
|
+
});
|
|
5903
|
+
|
|
5904
|
+
return createBreadcrumb({
|
|
5905
|
+
...breadcrumb,
|
|
5906
|
+
data: {
|
|
5907
|
+
...breadcrumb.data,
|
|
5908
|
+
arguments: normalizedArgs,
|
|
5909
|
+
...(isTruncated ? { _meta: { warnings: ['CONSOLE_ARG_TRUNCATED'] } } : {}),
|
|
5910
|
+
},
|
|
5911
|
+
});
|
|
5912
|
+
}
|
|
5913
|
+
|
|
5914
|
+
function isBreadcrumbWithCategory(breadcrumb) {
|
|
5915
|
+
return !!breadcrumb.category;
|
|
5916
|
+
}
|
|
5917
|
+
|
|
5832
5918
|
/**
|
|
5833
5919
|
* Returns true if we think the given event is an error originating inside of rrweb.
|
|
5834
5920
|
*/
|
|
@@ -5906,12 +5992,7 @@ function shouldSampleForBufferEvent(replay, event) {
|
|
|
5906
5992
|
/**
|
|
5907
5993
|
* Returns a listener to be added to `addEventProcessor(listener)`.
|
|
5908
5994
|
*/
|
|
5909
|
-
function handleGlobalEventListener(
|
|
5910
|
-
replay,
|
|
5911
|
-
includeAfterSendEventHandling = false,
|
|
5912
|
-
) {
|
|
5913
|
-
const afterSendHandler = includeAfterSendEventHandling ? handleAfterSendEvent(replay) : undefined;
|
|
5914
|
-
|
|
5995
|
+
function handleGlobalEventListener(replay) {
|
|
5915
5996
|
return Object.assign(
|
|
5916
5997
|
(event, hint) => {
|
|
5917
5998
|
// Do nothing if replay has been disabled
|
|
@@ -5967,13 +6048,6 @@ function handleGlobalEventListener(
|
|
|
5967
6048
|
event.tags = { ...event.tags, replayId: replay.getSessionId() };
|
|
5968
6049
|
}
|
|
5969
6050
|
|
|
5970
|
-
// In cases where a custom client is used that does not support the new hooks (yet),
|
|
5971
|
-
// we manually call this hook method here
|
|
5972
|
-
if (afterSendHandler) {
|
|
5973
|
-
// Pretend the error had a 200 response so we always capture it
|
|
5974
|
-
afterSendHandler(event, { statusCode: 200 });
|
|
5975
|
-
}
|
|
5976
|
-
|
|
5977
6051
|
return event;
|
|
5978
6052
|
},
|
|
5979
6053
|
{ id: 'Replay' },
|
|
@@ -6090,97 +6164,14 @@ function addNetworkBreadcrumb(
|
|
|
6090
6164
|
});
|
|
6091
6165
|
}
|
|
6092
6166
|
|
|
6093
|
-
/** only exported for tests */
|
|
6094
|
-
function handleFetch(handlerData) {
|
|
6095
|
-
const { startTimestamp, endTimestamp, fetchData, response } = handlerData;
|
|
6096
|
-
|
|
6097
|
-
if (!endTimestamp) {
|
|
6098
|
-
return null;
|
|
6099
|
-
}
|
|
6100
|
-
|
|
6101
|
-
// This is only used as a fallback, so we know the body sizes are never set here
|
|
6102
|
-
const { method, url } = fetchData;
|
|
6103
|
-
|
|
6104
|
-
return {
|
|
6105
|
-
type: 'resource.fetch',
|
|
6106
|
-
start: startTimestamp / 1000,
|
|
6107
|
-
end: endTimestamp / 1000,
|
|
6108
|
-
name: url,
|
|
6109
|
-
data: {
|
|
6110
|
-
method,
|
|
6111
|
-
statusCode: response ? (response ).status : undefined,
|
|
6112
|
-
},
|
|
6113
|
-
};
|
|
6114
|
-
}
|
|
6115
|
-
|
|
6116
|
-
/**
|
|
6117
|
-
* Returns a listener to be added to `addFetchInstrumentationHandler(listener)`.
|
|
6118
|
-
*/
|
|
6119
|
-
function handleFetchSpanListener(replay) {
|
|
6120
|
-
return (handlerData) => {
|
|
6121
|
-
if (!replay.isEnabled()) {
|
|
6122
|
-
return;
|
|
6123
|
-
}
|
|
6124
|
-
|
|
6125
|
-
const result = handleFetch(handlerData);
|
|
6126
|
-
|
|
6127
|
-
addNetworkBreadcrumb(replay, result);
|
|
6128
|
-
};
|
|
6129
|
-
}
|
|
6130
|
-
|
|
6131
|
-
/** only exported for tests */
|
|
6132
|
-
function handleXhr(handlerData) {
|
|
6133
|
-
const { startTimestamp, endTimestamp, xhr } = handlerData;
|
|
6134
|
-
|
|
6135
|
-
const sentryXhrData = xhr[SENTRY_XHR_DATA_KEY];
|
|
6136
|
-
|
|
6137
|
-
if (!startTimestamp || !endTimestamp || !sentryXhrData) {
|
|
6138
|
-
return null;
|
|
6139
|
-
}
|
|
6140
|
-
|
|
6141
|
-
// This is only used as a fallback, so we know the body sizes are never set here
|
|
6142
|
-
const { method, url, status_code: statusCode } = sentryXhrData;
|
|
6143
|
-
|
|
6144
|
-
if (url === undefined) {
|
|
6145
|
-
return null;
|
|
6146
|
-
}
|
|
6147
|
-
|
|
6148
|
-
return {
|
|
6149
|
-
type: 'resource.xhr',
|
|
6150
|
-
name: url,
|
|
6151
|
-
start: startTimestamp / 1000,
|
|
6152
|
-
end: endTimestamp / 1000,
|
|
6153
|
-
data: {
|
|
6154
|
-
method,
|
|
6155
|
-
statusCode,
|
|
6156
|
-
},
|
|
6157
|
-
};
|
|
6158
|
-
}
|
|
6159
|
-
|
|
6160
|
-
/**
|
|
6161
|
-
* Returns a listener to be added to `addXhrInstrumentationHandler(listener)`.
|
|
6162
|
-
*/
|
|
6163
|
-
function handleXhrSpanListener(replay) {
|
|
6164
|
-
return (handlerData) => {
|
|
6165
|
-
if (!replay.isEnabled()) {
|
|
6166
|
-
return;
|
|
6167
|
-
}
|
|
6168
|
-
|
|
6169
|
-
const result = handleXhr(handlerData);
|
|
6170
|
-
|
|
6171
|
-
addNetworkBreadcrumb(replay, result);
|
|
6172
|
-
};
|
|
6173
|
-
}
|
|
6174
|
-
|
|
6175
6167
|
/** Get the size of a body. */
|
|
6176
|
-
function getBodySize(
|
|
6177
|
-
body,
|
|
6178
|
-
textEncoder,
|
|
6179
|
-
) {
|
|
6168
|
+
function getBodySize(body) {
|
|
6180
6169
|
if (!body) {
|
|
6181
6170
|
return undefined;
|
|
6182
6171
|
}
|
|
6183
6172
|
|
|
6173
|
+
const textEncoder = new TextEncoder();
|
|
6174
|
+
|
|
6184
6175
|
try {
|
|
6185
6176
|
if (typeof body === 'string') {
|
|
6186
6177
|
return textEncoder.encode(body).length;
|
|
@@ -6480,12 +6471,11 @@ async function captureFetchBreadcrumbToReplay(
|
|
|
6480
6471
|
function enrichFetchBreadcrumb(
|
|
6481
6472
|
breadcrumb,
|
|
6482
6473
|
hint,
|
|
6483
|
-
options,
|
|
6484
6474
|
) {
|
|
6485
6475
|
const { input, response } = hint;
|
|
6486
6476
|
|
|
6487
6477
|
const body = input ? _getFetchRequestArgBody(input) : undefined;
|
|
6488
|
-
const reqSize = getBodySize(body
|
|
6478
|
+
const reqSize = getBodySize(body);
|
|
6489
6479
|
|
|
6490
6480
|
const resSize = response ? parseContentLengthHeader(response.headers.get('content-length')) : undefined;
|
|
6491
6481
|
|
|
@@ -6500,9 +6490,7 @@ function enrichFetchBreadcrumb(
|
|
|
6500
6490
|
async function _prepareFetchData(
|
|
6501
6491
|
breadcrumb,
|
|
6502
6492
|
hint,
|
|
6503
|
-
options
|
|
6504
|
-
|
|
6505
|
-
,
|
|
6493
|
+
options,
|
|
6506
6494
|
) {
|
|
6507
6495
|
const now = Date.now();
|
|
6508
6496
|
const { startTimestamp = now, endTimestamp = now } = hint;
|
|
@@ -6562,11 +6550,8 @@ async function _getResponseInfo(
|
|
|
6562
6550
|
captureDetails,
|
|
6563
6551
|
{
|
|
6564
6552
|
networkCaptureBodies,
|
|
6565
|
-
textEncoder,
|
|
6566
6553
|
networkResponseHeaders,
|
|
6567
|
-
}
|
|
6568
|
-
|
|
6569
|
-
,
|
|
6554
|
+
},
|
|
6570
6555
|
response,
|
|
6571
6556
|
responseBodySize,
|
|
6572
6557
|
) {
|
|
@@ -6583,7 +6568,7 @@ async function _getResponseInfo(
|
|
|
6583
6568
|
const [bodyText, warning] = await _parseFetchResponseBody(response);
|
|
6584
6569
|
const result = getResponseData(bodyText, {
|
|
6585
6570
|
networkCaptureBodies,
|
|
6586
|
-
|
|
6571
|
+
|
|
6587
6572
|
responseBodySize,
|
|
6588
6573
|
captureDetails,
|
|
6589
6574
|
headers,
|
|
@@ -6600,7 +6585,6 @@ function getResponseData(
|
|
|
6600
6585
|
bodyText,
|
|
6601
6586
|
{
|
|
6602
6587
|
networkCaptureBodies,
|
|
6603
|
-
textEncoder,
|
|
6604
6588
|
responseBodySize,
|
|
6605
6589
|
captureDetails,
|
|
6606
6590
|
headers,
|
|
@@ -6610,9 +6594,7 @@ function getResponseData(
|
|
|
6610
6594
|
) {
|
|
6611
6595
|
try {
|
|
6612
6596
|
const size =
|
|
6613
|
-
bodyText && bodyText.length && responseBodySize === undefined
|
|
6614
|
-
? getBodySize(bodyText, textEncoder)
|
|
6615
|
-
: responseBodySize;
|
|
6597
|
+
bodyText && bodyText.length && responseBodySize === undefined ? getBodySize(bodyText) : responseBodySize;
|
|
6616
6598
|
|
|
6617
6599
|
if (!captureDetails) {
|
|
6618
6600
|
return buildSkippedNetworkRequestOrResponse(size);
|
|
@@ -6767,7 +6749,6 @@ async function captureXhrBreadcrumbToReplay(
|
|
|
6767
6749
|
function enrichXhrBreadcrumb(
|
|
6768
6750
|
breadcrumb,
|
|
6769
6751
|
hint,
|
|
6770
|
-
options,
|
|
6771
6752
|
) {
|
|
6772
6753
|
const { xhr, input } = hint;
|
|
6773
6754
|
|
|
@@ -6775,10 +6756,10 @@ function enrichXhrBreadcrumb(
|
|
|
6775
6756
|
return;
|
|
6776
6757
|
}
|
|
6777
6758
|
|
|
6778
|
-
const reqSize = getBodySize(input
|
|
6759
|
+
const reqSize = getBodySize(input);
|
|
6779
6760
|
const resSize = xhr.getResponseHeader('content-length')
|
|
6780
6761
|
? parseContentLengthHeader(xhr.getResponseHeader('content-length'))
|
|
6781
|
-
: _getBodySize(xhr.response, xhr.responseType
|
|
6762
|
+
: _getBodySize(xhr.response, xhr.responseType);
|
|
6782
6763
|
|
|
6783
6764
|
if (reqSize !== undefined) {
|
|
6784
6765
|
breadcrumb.data.request_body_size = reqSize;
|
|
@@ -6925,11 +6906,10 @@ function _parseXhrResponse(
|
|
|
6925
6906
|
function _getBodySize(
|
|
6926
6907
|
body,
|
|
6927
6908
|
responseType,
|
|
6928
|
-
textEncoder,
|
|
6929
6909
|
) {
|
|
6930
6910
|
try {
|
|
6931
6911
|
const bodyStr = responseType === 'json' && body && typeof body === 'object' ? JSON.stringify(body) : body;
|
|
6932
|
-
return getBodySize(bodyStr
|
|
6912
|
+
return getBodySize(bodyStr);
|
|
6933
6913
|
} catch (e3) {
|
|
6934
6914
|
return undefined;
|
|
6935
6915
|
}
|
|
@@ -6945,8 +6925,6 @@ function handleNetworkBreadcrumbs(replay) {
|
|
|
6945
6925
|
const client = getClient();
|
|
6946
6926
|
|
|
6947
6927
|
try {
|
|
6948
|
-
const textEncoder = new TextEncoder();
|
|
6949
|
-
|
|
6950
6928
|
const {
|
|
6951
6929
|
networkDetailAllowUrls,
|
|
6952
6930
|
networkDetailDenyUrls,
|
|
@@ -6957,7 +6935,6 @@ function handleNetworkBreadcrumbs(replay) {
|
|
|
6957
6935
|
|
|
6958
6936
|
const options = {
|
|
6959
6937
|
replay,
|
|
6960
|
-
textEncoder,
|
|
6961
6938
|
networkDetailAllowUrls,
|
|
6962
6939
|
networkDetailDenyUrls,
|
|
6963
6940
|
networkCaptureBodies,
|
|
@@ -6965,12 +6942,8 @@ function handleNetworkBreadcrumbs(replay) {
|
|
|
6965
6942
|
networkResponseHeaders,
|
|
6966
6943
|
};
|
|
6967
6944
|
|
|
6968
|
-
if (client
|
|
6945
|
+
if (client) {
|
|
6969
6946
|
client.on('beforeAddBreadcrumb', (breadcrumb, hint) => beforeAddNetworkBreadcrumb(options, breadcrumb, hint));
|
|
6970
|
-
} else {
|
|
6971
|
-
// Fallback behavior
|
|
6972
|
-
addFetchInstrumentationHandler(handleFetchSpanListener(replay));
|
|
6973
|
-
addXhrInstrumentationHandler(handleXhrSpanListener(replay));
|
|
6974
6947
|
}
|
|
6975
6948
|
} catch (e2) {
|
|
6976
6949
|
// Do nothing
|
|
@@ -6992,7 +6965,7 @@ function beforeAddNetworkBreadcrumb(
|
|
|
6992
6965
|
// This has to be sync, as we need to ensure the breadcrumb is enriched in the same tick
|
|
6993
6966
|
// Because the hook runs synchronously, and the breadcrumb is afterwards passed on
|
|
6994
6967
|
// So any async mutations to it will not be reflected in the final breadcrumb
|
|
6995
|
-
enrichXhrBreadcrumb(breadcrumb, hint
|
|
6968
|
+
enrichXhrBreadcrumb(breadcrumb, hint);
|
|
6996
6969
|
|
|
6997
6970
|
// This call should not reject
|
|
6998
6971
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
@@ -7003,7 +6976,7 @@ function beforeAddNetworkBreadcrumb(
|
|
|
7003
6976
|
// This has to be sync, as we need to ensure the breadcrumb is enriched in the same tick
|
|
7004
6977
|
// Because the hook runs synchronously, and the breadcrumb is afterwards passed on
|
|
7005
6978
|
// So any async mutations to it will not be reflected in the final breadcrumb
|
|
7006
|
-
enrichFetchBreadcrumb(breadcrumb, hint
|
|
6979
|
+
enrichFetchBreadcrumb(breadcrumb, hint);
|
|
7007
6980
|
|
|
7008
6981
|
// This call should not reject
|
|
7009
6982
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
@@ -7030,138 +7003,25 @@ function _isFetchHint(hint) {
|
|
|
7030
7003
|
return hint && hint.response;
|
|
7031
7004
|
}
|
|
7032
7005
|
|
|
7033
|
-
let _LAST_BREADCRUMB = null;
|
|
7034
|
-
|
|
7035
|
-
function isBreadcrumbWithCategory(breadcrumb) {
|
|
7036
|
-
return !!breadcrumb.category;
|
|
7037
|
-
}
|
|
7038
|
-
|
|
7039
|
-
const handleScopeListener =
|
|
7040
|
-
(replay) =>
|
|
7041
|
-
(scope) => {
|
|
7042
|
-
if (!replay.isEnabled()) {
|
|
7043
|
-
return;
|
|
7044
|
-
}
|
|
7045
|
-
|
|
7046
|
-
const result = handleScope(scope);
|
|
7047
|
-
|
|
7048
|
-
if (!result) {
|
|
7049
|
-
return;
|
|
7050
|
-
}
|
|
7051
|
-
|
|
7052
|
-
addBreadcrumbEvent(replay, result);
|
|
7053
|
-
};
|
|
7054
|
-
|
|
7055
|
-
/**
|
|
7056
|
-
* An event handler to handle scope changes.
|
|
7057
|
-
*/
|
|
7058
|
-
function handleScope(scope) {
|
|
7059
|
-
// TODO (v8): Remove this guard. This was put in place because we introduced
|
|
7060
|
-
// Scope.getLastBreadcrumb mid-v7 which caused incompatibilities with older SDKs.
|
|
7061
|
-
// For now, we'll just return null if the method doesn't exist but we should eventually
|
|
7062
|
-
// get rid of this guard.
|
|
7063
|
-
const newBreadcrumb = scope.getLastBreadcrumb && scope.getLastBreadcrumb();
|
|
7064
|
-
|
|
7065
|
-
// Listener can be called when breadcrumbs have not changed, so we store the
|
|
7066
|
-
// reference to the last crumb and only return a crumb if it has changed
|
|
7067
|
-
if (_LAST_BREADCRUMB === newBreadcrumb || !newBreadcrumb) {
|
|
7068
|
-
return null;
|
|
7069
|
-
}
|
|
7070
|
-
|
|
7071
|
-
_LAST_BREADCRUMB = newBreadcrumb;
|
|
7072
|
-
|
|
7073
|
-
if (
|
|
7074
|
-
!isBreadcrumbWithCategory(newBreadcrumb) ||
|
|
7075
|
-
['fetch', 'xhr', 'sentry.event', 'sentry.transaction'].includes(newBreadcrumb.category) ||
|
|
7076
|
-
newBreadcrumb.category.startsWith('ui.')
|
|
7077
|
-
) {
|
|
7078
|
-
return null;
|
|
7079
|
-
}
|
|
7080
|
-
|
|
7081
|
-
if (newBreadcrumb.category === 'console') {
|
|
7082
|
-
return normalizeConsoleBreadcrumb(newBreadcrumb);
|
|
7083
|
-
}
|
|
7084
|
-
|
|
7085
|
-
return createBreadcrumb(newBreadcrumb);
|
|
7086
|
-
}
|
|
7087
|
-
|
|
7088
|
-
/** exported for tests only */
|
|
7089
|
-
function normalizeConsoleBreadcrumb(
|
|
7090
|
-
breadcrumb,
|
|
7091
|
-
) {
|
|
7092
|
-
const args = breadcrumb.data && breadcrumb.data.arguments;
|
|
7093
|
-
|
|
7094
|
-
if (!Array.isArray(args) || args.length === 0) {
|
|
7095
|
-
return createBreadcrumb(breadcrumb);
|
|
7096
|
-
}
|
|
7097
|
-
|
|
7098
|
-
let isTruncated = false;
|
|
7099
|
-
|
|
7100
|
-
// Avoid giant args captures
|
|
7101
|
-
const normalizedArgs = args.map(arg => {
|
|
7102
|
-
if (!arg) {
|
|
7103
|
-
return arg;
|
|
7104
|
-
}
|
|
7105
|
-
if (typeof arg === 'string') {
|
|
7106
|
-
if (arg.length > CONSOLE_ARG_MAX_SIZE) {
|
|
7107
|
-
isTruncated = true;
|
|
7108
|
-
return `${arg.slice(0, CONSOLE_ARG_MAX_SIZE)}…`;
|
|
7109
|
-
}
|
|
7110
|
-
|
|
7111
|
-
return arg;
|
|
7112
|
-
}
|
|
7113
|
-
if (typeof arg === 'object') {
|
|
7114
|
-
try {
|
|
7115
|
-
const normalizedArg = normalize(arg, 7);
|
|
7116
|
-
const stringified = JSON.stringify(normalizedArg);
|
|
7117
|
-
if (stringified.length > CONSOLE_ARG_MAX_SIZE) {
|
|
7118
|
-
isTruncated = true;
|
|
7119
|
-
// We use the pretty printed JSON string here as a base
|
|
7120
|
-
return `${JSON.stringify(normalizedArg, null, 2).slice(0, CONSOLE_ARG_MAX_SIZE)}…`;
|
|
7121
|
-
}
|
|
7122
|
-
return normalizedArg;
|
|
7123
|
-
} catch (e) {
|
|
7124
|
-
// fall back to default
|
|
7125
|
-
}
|
|
7126
|
-
}
|
|
7127
|
-
|
|
7128
|
-
return arg;
|
|
7129
|
-
});
|
|
7130
|
-
|
|
7131
|
-
return createBreadcrumb({
|
|
7132
|
-
...breadcrumb,
|
|
7133
|
-
data: {
|
|
7134
|
-
...breadcrumb.data,
|
|
7135
|
-
arguments: normalizedArgs,
|
|
7136
|
-
...(isTruncated ? { _meta: { warnings: ['CONSOLE_ARG_TRUNCATED'] } } : {}),
|
|
7137
|
-
},
|
|
7138
|
-
});
|
|
7139
|
-
}
|
|
7140
|
-
|
|
7141
7006
|
/**
|
|
7142
7007
|
* Add global listeners that cannot be removed.
|
|
7143
7008
|
*/
|
|
7144
7009
|
function addGlobalListeners(replay) {
|
|
7145
7010
|
// Listeners from core SDK //
|
|
7146
|
-
const scope = getCurrentScope();
|
|
7147
7011
|
const client = getClient();
|
|
7148
7012
|
|
|
7149
|
-
scope.addScopeListener(handleScopeListener(replay));
|
|
7150
7013
|
addClickKeypressInstrumentationHandler(handleDomListener(replay));
|
|
7151
7014
|
addHistoryInstrumentationHandler(handleHistorySpanListener(replay));
|
|
7015
|
+
handleBreadcrumbs(replay);
|
|
7152
7016
|
handleNetworkBreadcrumbs(replay);
|
|
7153
7017
|
|
|
7154
7018
|
// Tag all (non replay) events that get sent to Sentry with the current
|
|
7155
7019
|
// replay ID so that we can reference them later in the UI
|
|
7156
|
-
const eventProcessor = handleGlobalEventListener(replay
|
|
7157
|
-
|
|
7158
|
-
client.addEventProcessor(eventProcessor);
|
|
7159
|
-
} else {
|
|
7160
|
-
addEventProcessor(eventProcessor);
|
|
7161
|
-
}
|
|
7020
|
+
const eventProcessor = handleGlobalEventListener(replay);
|
|
7021
|
+
addEventProcessor(eventProcessor);
|
|
7162
7022
|
|
|
7163
7023
|
// If a custom client has no hooks yet, we continue to use the "old" implementation
|
|
7164
|
-
if (
|
|
7024
|
+
if (client) {
|
|
7165
7025
|
client.on('beforeSendEvent', handleBeforeSendEvent(replay));
|
|
7166
7026
|
client.on('afterSendEvent', handleAfterSendEvent(replay));
|
|
7167
7027
|
client.on('createDsc', (dsc) => {
|
|
@@ -7199,11 +7059,6 @@ function addGlobalListeners(replay) {
|
|
|
7199
7059
|
}
|
|
7200
7060
|
}
|
|
7201
7061
|
|
|
7202
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
7203
|
-
function hasHooks(client) {
|
|
7204
|
-
return !!(client && client.on);
|
|
7205
|
-
}
|
|
7206
|
-
|
|
7207
7062
|
/**
|
|
7208
7063
|
* Create a "span" for the total amount of memory being used by JS objects
|
|
7209
7064
|
* (including v8 internal objects).
|
|
@@ -7525,9 +7380,7 @@ async function prepareReplayEvent({
|
|
|
7525
7380
|
|
|
7526
7381
|
const eventHint = { event_id, integrations };
|
|
7527
7382
|
|
|
7528
|
-
|
|
7529
|
-
client.emit('preprocessEvent', event, eventHint);
|
|
7530
|
-
}
|
|
7383
|
+
client.emit('preprocessEvent', event, eventHint);
|
|
7531
7384
|
|
|
7532
7385
|
const preparedEvent = (await prepareEvent(
|
|
7533
7386
|
client.getOptions(),
|
|
@@ -7549,7 +7402,7 @@ async function prepareReplayEvent({
|
|
|
7549
7402
|
preparedEvent.platform = preparedEvent.platform || 'javascript';
|
|
7550
7403
|
|
|
7551
7404
|
// extract the SDK name because `client._prepareEvent` doesn't add it to the event
|
|
7552
|
-
const metadata = client.getSdkMetadata
|
|
7405
|
+
const metadata = client.getSdkMetadata();
|
|
7553
7406
|
const { name, version } = (metadata && metadata.sdk) || {};
|
|
7554
7407
|
|
|
7555
7408
|
preparedEvent.sdk = {
|
|
@@ -7587,7 +7440,7 @@ async function sendReplayRequest({
|
|
|
7587
7440
|
const dsn = client && client.getDsn();
|
|
7588
7441
|
|
|
7589
7442
|
if (!client || !transport || !dsn || !session.sampled) {
|
|
7590
|
-
return;
|
|
7443
|
+
return resolvedSyncPromise({});
|
|
7591
7444
|
}
|
|
7592
7445
|
|
|
7593
7446
|
const baseEvent = {
|
|
@@ -7608,7 +7461,7 @@ async function sendReplayRequest({
|
|
|
7608
7461
|
// Taken from baseclient's `_processEvent` method, where this is handled for errors/transactions
|
|
7609
7462
|
client.recordDroppedEvent('event_processor', 'replay', baseEvent);
|
|
7610
7463
|
logInfo('An event processor returned `null`, will not send event.');
|
|
7611
|
-
return;
|
|
7464
|
+
return resolvedSyncPromise({});
|
|
7612
7465
|
}
|
|
7613
7466
|
|
|
7614
7467
|
/*
|
|
@@ -7670,11 +7523,6 @@ async function sendReplayRequest({
|
|
|
7670
7523
|
throw error;
|
|
7671
7524
|
}
|
|
7672
7525
|
|
|
7673
|
-
// TODO (v8): we can remove this guard once transport.send's type signature doesn't include void anymore
|
|
7674
|
-
if (!response) {
|
|
7675
|
-
return response;
|
|
7676
|
-
}
|
|
7677
|
-
|
|
7678
7526
|
// If the status code is invalid, we want to immediately stop & not retry
|
|
7679
7527
|
if (typeof response.statusCode === 'number' && (response.statusCode < 200 || response.statusCode >= 300)) {
|
|
7680
7528
|
throw new TransportStatusCodeError(response.statusCode);
|
|
@@ -9533,12 +9381,9 @@ function _getMergedNetworkHeaders(headers) {
|
|
|
9533
9381
|
/**
|
|
9534
9382
|
* This is a small utility to get a type-safe instance of the Replay integration.
|
|
9535
9383
|
*/
|
|
9536
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
9537
9384
|
function getReplay() {
|
|
9538
9385
|
const client = getClient();
|
|
9539
|
-
return (
|
|
9540
|
-
client && client.getIntegrationByName && client.getIntegrationByName('Replay')
|
|
9541
|
-
);
|
|
9386
|
+
return client && client.getIntegrationByName('Replay');
|
|
9542
9387
|
}
|
|
9543
9388
|
|
|
9544
9389
|
export { Replay, getReplay, replayIntegration };
|