@@ -20,7 +20,7 @@ import {
20
20
*/
21
21
export async function captureXhrBreadcrumbToReplay (
22
22
breadcrumb : Breadcrumb & { data : XhrBreadcrumbData } ,
23
- hint : XhrHint ,
23
+ hint : Partial < XhrHint > ,
24
24
options : ReplayNetworkOptions & { replay : ReplayContainer } ,
25
25
) : Promise < void > {
26
26
try {
@@ -41,11 +41,15 @@ export async function captureXhrBreadcrumbToReplay(
41
41
*/
42
42
export function enrichXhrBreadcrumb (
43
43
breadcrumb : Breadcrumb & { data : XhrBreadcrumbData } ,
44
- hint : XhrHint ,
44
+ hint : Partial < XhrHint > ,
45
45
options : { textEncoder : TextEncoderInternal } ,
46
46
) : void {
47
47
const { xhr, input } = hint ;
48
48
49
+ if ( ! xhr ) {
50
+ return ;
51
+ }
52
+
49
53
const reqSize = getBodySize ( input , options . textEncoder ) ;
50
54
const resSize = xhr . getResponseHeader ( 'content-length' )
51
55
? parseContentLengthHeader ( xhr . getResponseHeader ( 'content-length' ) )
@@ -61,10 +65,11 @@ export function enrichXhrBreadcrumb(
61
65
62
66
function _prepareXhrData (
63
67
breadcrumb : Breadcrumb & { data : XhrBreadcrumbData } ,
64
- hint : XhrHint ,
68
+ hint : Partial < XhrHint > ,
65
69
options : ReplayNetworkOptions ,
66
70
) : ReplayNetworkRequestData | null {
67
- const { startTimestamp, endTimestamp, input, xhr } = hint ;
71
+ const now = Date . now ( ) ;
72
+ const { startTimestamp = now , endTimestamp = now , input, xhr } = hint ;
68
73
69
74
const {
70
75
url,
@@ -78,7 +83,7 @@ function _prepareXhrData(
78
83
return null ;
79
84
}
80
85
81
- if ( ! urlMatches ( url , options . networkDetailAllowUrls ) || urlMatches ( url , options . networkDetailDenyUrls ) ) {
86
+ if ( ! xhr || ! urlMatches ( url , options . networkDetailAllowUrls ) || urlMatches ( url , options . networkDetailDenyUrls ) ) {
82
87
const request = buildSkippedNetworkRequestOrResponse ( requestBodySize ) ;
83
88
const response = buildSkippedNetworkRequestOrResponse ( responseBodySize ) ;
84
89
return {
@@ -98,16 +103,11 @@ function _prepareXhrData(
98
103
: { } ;
99
104
const networkResponseHeaders = getAllowedHeaders ( getResponseHeaders ( xhr ) , options . networkResponseHeaders ) ;
100
105
101
- const request = buildNetworkRequestOrResponse (
102
- networkRequestHeaders ,
103
- requestBodySize ,
104
- options . networkCaptureBodies ? getBodyString ( input ) : undefined ,
105
- ) ;
106
- const response = buildNetworkRequestOrResponse (
107
- networkResponseHeaders ,
108
- responseBodySize ,
109
- options . networkCaptureBodies ? hint . xhr . responseText : undefined ,
110
- ) ;
106
+ const requestBody = options . networkCaptureBodies ? getBodyString ( input ) : undefined ;
107
+ const responseBody = options . networkCaptureBodies ? _getXhrResponseBody ( xhr ) : undefined ;
108
+
109
+ const request = buildNetworkRequestOrResponse ( networkRequestHeaders , requestBodySize , requestBody ) ;
110
+ const response = buildNetworkRequestOrResponse ( networkResponseHeaders , responseBodySize , responseBody ) ;
111
111
112
112
return {
113
113
startTimestamp,
@@ -133,3 +133,17 @@ function getResponseHeaders(xhr: XMLHttpRequest): Record<string, string> {
133
133
return acc ;
134
134
} , { } ) ;
135
135
}
136
+
137
+ function _getXhrResponseBody ( xhr : XMLHttpRequest ) : string | undefined {
138
+ try {
139
+ return xhr . responseText ;
140
+ } catch { } // eslint-disable-line no-empty
141
+
142
+ // Try to manually parse the response body, if responseText fails
143
+ try {
144
+ const response = xhr . response ;
145
+ return getBodyString ( response ) ;
146
+ } catch { } // eslint-disable-line no-empty
147
+
148
+ return undefined ;
149
+ }
0 commit comments