@sentry/replay 7.80.0 → 7.80.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/cjs/index.js +92 -31
- package/cjs/index.js.map +1 -1
- package/esm/index.js +92 -31
- package/esm/index.js.map +1 -1
- package/package.json +6 -6
- package/types/coreHandlers/handleGlobalEvent.d.ts.map +1 -1
- package/types/coreHandlers/util/addFeedbackBreadcrumb.d.ts +7 -0
- package/types/coreHandlers/util/addFeedbackBreadcrumb.d.ts.map +1 -0
- package/types/coreHandlers/util/fetchUtils.d.ts +2 -2
- package/types/coreHandlers/util/fetchUtils.d.ts.map +1 -1
- package/types/coreHandlers/util/networkUtils.d.ts.map +1 -1
- package/types/coreHandlers/util/xhrUtils.d.ts +2 -2
- package/types/coreHandlers/util/xhrUtils.d.ts.map +1 -1
- package/types/types/replayFrame.d.ts +8 -1
- package/types/types/replayFrame.d.ts.map +1 -1
- package/types/util/eventUtils.d.ts +3 -1
- package/types/util/eventUtils.d.ts.map +1 -1
- package/types-ts3.8/coreHandlers/util/addFeedbackBreadcrumb.d.ts +7 -0
- package/types-ts3.8/coreHandlers/util/fetchUtils.d.ts +2 -2
- package/types-ts3.8/coreHandlers/util/xhrUtils.d.ts +2 -2
- package/types-ts3.8/types/replayFrame.d.ts +8 -1
- package/types-ts3.8/util/eventUtils.d.ts +3 -1
package/esm/index.js
CHANGED
|
@@ -5538,6 +5538,11 @@ function isReplayEvent(event) {
|
|
|
5538
5538
|
return event.type === 'replay_event';
|
|
5539
5539
|
}
|
|
5540
5540
|
|
|
5541
|
+
/** If the event is a feedback event */
|
|
5542
|
+
function isFeedbackEvent(event) {
|
|
5543
|
+
return event.type === 'feedback';
|
|
5544
|
+
}
|
|
5545
|
+
|
|
5541
5546
|
/**
|
|
5542
5547
|
* Returns a listener to be added to `client.on('afterSendErrorEvent, listener)`.
|
|
5543
5548
|
*/
|
|
@@ -5642,6 +5647,37 @@ function isRrwebError(event, hint) {
|
|
|
5642
5647
|
return false;
|
|
5643
5648
|
}
|
|
5644
5649
|
|
|
5650
|
+
/**
|
|
5651
|
+
* Add a feedback breadcrumb event to replay.
|
|
5652
|
+
*/
|
|
5653
|
+
function addFeedbackBreadcrumb(replay, event) {
|
|
5654
|
+
replay.triggerUserActivity();
|
|
5655
|
+
replay.addUpdate(() => {
|
|
5656
|
+
if (!event.timestamp) {
|
|
5657
|
+
// Ignore events that don't have timestamps (this shouldn't happen, more of a typing issue)
|
|
5658
|
+
// Return true here so that we don't flush
|
|
5659
|
+
return true;
|
|
5660
|
+
}
|
|
5661
|
+
|
|
5662
|
+
void replay.throttledAddEvent({
|
|
5663
|
+
type: EventType.Custom,
|
|
5664
|
+
timestamp: event.timestamp * 1000,
|
|
5665
|
+
data: {
|
|
5666
|
+
timestamp: event.timestamp,
|
|
5667
|
+
tag: 'breadcrumb',
|
|
5668
|
+
payload: {
|
|
5669
|
+
category: 'sentry.feedback',
|
|
5670
|
+
data: {
|
|
5671
|
+
feedbackId: event.event_id,
|
|
5672
|
+
},
|
|
5673
|
+
},
|
|
5674
|
+
},
|
|
5675
|
+
});
|
|
5676
|
+
|
|
5677
|
+
return false;
|
|
5678
|
+
});
|
|
5679
|
+
}
|
|
5680
|
+
|
|
5645
5681
|
/**
|
|
5646
5682
|
* Determine if event should be sampled (only applies in buffer mode).
|
|
5647
5683
|
* When an event is captured by `hanldleGlobalEvent`, when in buffer mode
|
|
@@ -5689,8 +5725,8 @@ function handleGlobalEventListener(
|
|
|
5689
5725
|
return event;
|
|
5690
5726
|
}
|
|
5691
5727
|
|
|
5692
|
-
// We only want to handle errors
|
|
5693
|
-
if (!isErrorEvent(event) && !isTransactionEvent(event)) {
|
|
5728
|
+
// We only want to handle errors, transactions, and feedbacks, nothing else
|
|
5729
|
+
if (!isErrorEvent(event) && !isTransactionEvent(event) && !isFeedbackEvent(event)) {
|
|
5694
5730
|
return event;
|
|
5695
5731
|
}
|
|
5696
5732
|
|
|
@@ -5700,6 +5736,12 @@ function handleGlobalEventListener(
|
|
|
5700
5736
|
return event;
|
|
5701
5737
|
}
|
|
5702
5738
|
|
|
5739
|
+
if (isFeedbackEvent(event)) {
|
|
5740
|
+
// Add a replay breadcrumb for this piece of feedback
|
|
5741
|
+
addFeedbackBreadcrumb(replay, event);
|
|
5742
|
+
return event;
|
|
5743
|
+
}
|
|
5744
|
+
|
|
5703
5745
|
// Unless `captureExceptions` is enabled, we want to ignore errors coming from rrweb
|
|
5704
5746
|
// As there can be a bunch of stuff going wrong in internals there, that we don't want to bubble up to users
|
|
5705
5747
|
if (isRrwebError(event, hint) && !replay.getOptions()._experiments.captureExceptions) {
|
|
@@ -5976,16 +6018,20 @@ function parseContentLengthHeader(header) {
|
|
|
5976
6018
|
|
|
5977
6019
|
/** Get the string representation of a body. */
|
|
5978
6020
|
function getBodyString(body) {
|
|
5979
|
-
|
|
5980
|
-
|
|
5981
|
-
|
|
6021
|
+
try {
|
|
6022
|
+
if (typeof body === 'string') {
|
|
6023
|
+
return body;
|
|
6024
|
+
}
|
|
5982
6025
|
|
|
5983
|
-
|
|
5984
|
-
|
|
5985
|
-
|
|
6026
|
+
if (body instanceof URLSearchParams) {
|
|
6027
|
+
return body.toString();
|
|
6028
|
+
}
|
|
5986
6029
|
|
|
5987
|
-
|
|
5988
|
-
|
|
6030
|
+
if (body instanceof FormData) {
|
|
6031
|
+
return _serializeFormData(body);
|
|
6032
|
+
}
|
|
6033
|
+
} catch (e2) {
|
|
6034
|
+
(typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.warn('[Replay] Failed to serialize body', body);
|
|
5989
6035
|
}
|
|
5990
6036
|
|
|
5991
6037
|
return undefined;
|
|
@@ -6097,7 +6143,6 @@ function normalizeNetworkBody(body)
|
|
|
6097
6143
|
}
|
|
6098
6144
|
|
|
6099
6145
|
const exceedsSizeLimit = body.length > NETWORK_BODY_MAX_SIZE;
|
|
6100
|
-
|
|
6101
6146
|
const isProbablyJson = _strIsProbablyJson(body);
|
|
6102
6147
|
|
|
6103
6148
|
if (exceedsSizeLimit) {
|
|
@@ -6122,7 +6167,7 @@ function normalizeNetworkBody(body)
|
|
|
6122
6167
|
return {
|
|
6123
6168
|
body: jsonBody,
|
|
6124
6169
|
};
|
|
6125
|
-
} catch (
|
|
6170
|
+
} catch (e4) {
|
|
6126
6171
|
// fall back to just send the body as string
|
|
6127
6172
|
}
|
|
6128
6173
|
}
|
|
@@ -6204,7 +6249,7 @@ function enrichFetchBreadcrumb(
|
|
|
6204
6249
|
) {
|
|
6205
6250
|
const { input, response } = hint;
|
|
6206
6251
|
|
|
6207
|
-
const body = _getFetchRequestArgBody(input);
|
|
6252
|
+
const body = input ? _getFetchRequestArgBody(input) : undefined;
|
|
6208
6253
|
const reqSize = getBodySize(body, options.textEncoder);
|
|
6209
6254
|
|
|
6210
6255
|
const resSize = response ? parseContentLengthHeader(response.headers.get('content-length')) : undefined;
|
|
@@ -6224,7 +6269,8 @@ async function _prepareFetchData(
|
|
|
6224
6269
|
|
|
6225
6270
|
,
|
|
6226
6271
|
) {
|
|
6227
|
-
const
|
|
6272
|
+
const now = Date.now();
|
|
6273
|
+
const { startTimestamp = now, endTimestamp = now } = hint;
|
|
6228
6274
|
|
|
6229
6275
|
const {
|
|
6230
6276
|
url,
|
|
@@ -6258,7 +6304,7 @@ function _getRequestInfo(
|
|
|
6258
6304
|
input,
|
|
6259
6305
|
requestBodySize,
|
|
6260
6306
|
) {
|
|
6261
|
-
const headers = getRequestHeaders(input, networkRequestHeaders);
|
|
6307
|
+
const headers = input ? getRequestHeaders(input, networkRequestHeaders) : {};
|
|
6262
6308
|
|
|
6263
6309
|
if (!networkCaptureBodies) {
|
|
6264
6310
|
return buildNetworkRequestOrResponse(headers, requestBodySize, undefined);
|
|
@@ -6286,9 +6332,9 @@ async function _getResponseInfo(
|
|
|
6286
6332
|
return buildSkippedNetworkRequestOrResponse(responseBodySize);
|
|
6287
6333
|
}
|
|
6288
6334
|
|
|
6289
|
-
const headers = getAllHeaders(response.headers, networkResponseHeaders);
|
|
6335
|
+
const headers = response ? getAllHeaders(response.headers, networkResponseHeaders) : {};
|
|
6290
6336
|
|
|
6291
|
-
if (!networkCaptureBodies && responseBodySize !== undefined) {
|
|
6337
|
+
if (!response || (!networkCaptureBodies && responseBodySize !== undefined)) {
|
|
6292
6338
|
return buildNetworkRequestOrResponse(headers, responseBodySize, undefined);
|
|
6293
6339
|
}
|
|
6294
6340
|
|
|
@@ -6312,7 +6358,8 @@ async function _getResponseInfo(
|
|
|
6312
6358
|
}
|
|
6313
6359
|
|
|
6314
6360
|
return buildNetworkRequestOrResponse(headers, size, undefined);
|
|
6315
|
-
} catch (
|
|
6361
|
+
} catch (error) {
|
|
6362
|
+
(typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.warn('[Replay] Failed to serialize response body', error);
|
|
6316
6363
|
// fallback
|
|
6317
6364
|
return buildNetworkRequestOrResponse(headers, responseBodySize, undefined);
|
|
6318
6365
|
}
|
|
@@ -6321,7 +6368,7 @@ async function _getResponseInfo(
|
|
|
6321
6368
|
async function _parseFetchBody(response) {
|
|
6322
6369
|
try {
|
|
6323
6370
|
return await response.text();
|
|
6324
|
-
} catch (
|
|
6371
|
+
} catch (e) {
|
|
6325
6372
|
return undefined;
|
|
6326
6373
|
}
|
|
6327
6374
|
}
|
|
@@ -6417,6 +6464,10 @@ function enrichXhrBreadcrumb(
|
|
|
6417
6464
|
) {
|
|
6418
6465
|
const { xhr, input } = hint;
|
|
6419
6466
|
|
|
6467
|
+
if (!xhr) {
|
|
6468
|
+
return;
|
|
6469
|
+
}
|
|
6470
|
+
|
|
6420
6471
|
const reqSize = getBodySize(input, options.textEncoder);
|
|
6421
6472
|
const resSize = xhr.getResponseHeader('content-length')
|
|
6422
6473
|
? parseContentLengthHeader(xhr.getResponseHeader('content-length'))
|
|
@@ -6435,7 +6486,8 @@ function _prepareXhrData(
|
|
|
6435
6486
|
hint,
|
|
6436
6487
|
options,
|
|
6437
6488
|
) {
|
|
6438
|
-
const
|
|
6489
|
+
const now = Date.now();
|
|
6490
|
+
const { startTimestamp = now, endTimestamp = now, input, xhr } = hint;
|
|
6439
6491
|
|
|
6440
6492
|
const {
|
|
6441
6493
|
url,
|
|
@@ -6449,7 +6501,7 @@ function _prepareXhrData(
|
|
|
6449
6501
|
return null;
|
|
6450
6502
|
}
|
|
6451
6503
|
|
|
6452
|
-
if (!urlMatches(url, options.networkDetailAllowUrls) || urlMatches(url, options.networkDetailDenyUrls)) {
|
|
6504
|
+
if (!xhr || !urlMatches(url, options.networkDetailAllowUrls) || urlMatches(url, options.networkDetailDenyUrls)) {
|
|
6453
6505
|
const request = buildSkippedNetworkRequestOrResponse(requestBodySize);
|
|
6454
6506
|
const response = buildSkippedNetworkRequestOrResponse(responseBodySize);
|
|
6455
6507
|
return {
|
|
@@ -6469,16 +6521,11 @@ function _prepareXhrData(
|
|
|
6469
6521
|
: {};
|
|
6470
6522
|
const networkResponseHeaders = getAllowedHeaders(getResponseHeaders(xhr), options.networkResponseHeaders);
|
|
6471
6523
|
|
|
6472
|
-
const
|
|
6473
|
-
|
|
6474
|
-
|
|
6475
|
-
|
|
6476
|
-
);
|
|
6477
|
-
const response = buildNetworkRequestOrResponse(
|
|
6478
|
-
networkResponseHeaders,
|
|
6479
|
-
responseBodySize,
|
|
6480
|
-
options.networkCaptureBodies ? hint.xhr.responseText : undefined,
|
|
6481
|
-
);
|
|
6524
|
+
const requestBody = options.networkCaptureBodies ? getBodyString(input) : undefined;
|
|
6525
|
+
const responseBody = options.networkCaptureBodies ? _getXhrResponseBody(xhr) : undefined;
|
|
6526
|
+
|
|
6527
|
+
const request = buildNetworkRequestOrResponse(networkRequestHeaders, requestBodySize, requestBody);
|
|
6528
|
+
const response = buildNetworkRequestOrResponse(networkResponseHeaders, responseBodySize, responseBody);
|
|
6482
6529
|
|
|
6483
6530
|
return {
|
|
6484
6531
|
startTimestamp,
|
|
@@ -6505,6 +6552,20 @@ function getResponseHeaders(xhr) {
|
|
|
6505
6552
|
}, {});
|
|
6506
6553
|
}
|
|
6507
6554
|
|
|
6555
|
+
function _getXhrResponseBody(xhr) {
|
|
6556
|
+
try {
|
|
6557
|
+
return xhr.responseText;
|
|
6558
|
+
} catch (e) {} // eslint-disable-line no-empty
|
|
6559
|
+
|
|
6560
|
+
// Try to manually parse the response body, if responseText fails
|
|
6561
|
+
try {
|
|
6562
|
+
const response = xhr.response;
|
|
6563
|
+
return getBodyString(response);
|
|
6564
|
+
} catch (e2) {} // eslint-disable-line no-empty
|
|
6565
|
+
|
|
6566
|
+
return undefined;
|
|
6567
|
+
}
|
|
6568
|
+
|
|
6508
6569
|
/**
|
|
6509
6570
|
* This method does two things:
|
|
6510
6571
|
* - It enriches the regular XHR/fetch breadcrumbs with request/response size data
|