@@ -95,13 +95,13 @@ export const XHR_PLUGIN_ID = 'xhr';
9595 */
9696export class XhrPlugin extends MonkeyPatched < XMLHttpRequest , 'send' | 'open' > {
9797 private config : HttpPluginConfig ;
98- private xhrMap : Map < XMLHttpRequest , XhrDetails > ;
98+ private map : Map < XMLHttpRequest , XhrDetails > ;
9999 private isSyntheticsUA : boolean ;
100100
101101 constructor ( config ?: PartialHttpPluginConfig ) {
102102 super ( XHR_PLUGIN_ID ) ;
103103 this . config = { ...defaultConfig , ...config } ;
104- this . xhrMap = new Map < XMLHttpRequest , XhrDetails > ( ) ;
104+ this . map = new Map < XMLHttpRequest , XhrDetails > ( ) ;
105105 this . isSyntheticsUA = navigator . userAgent . includes (
106106 'CloudWatchSynthetics'
107107 ) ;
@@ -111,6 +111,10 @@ export class XhrPlugin extends MonkeyPatched<XMLHttpRequest, 'send' | 'open'> {
111111 this . enable ( ) ;
112112 }
113113
114+ get cacheSize ( ) {
115+ return this . map . size ;
116+ }
117+
114118 protected get patches ( ) {
115119 return [
116120 {
@@ -139,103 +143,110 @@ export class XhrPlugin extends MonkeyPatched<XMLHttpRequest, 'send' | 'open'> {
139143 } ;
140144
141145 private handleXhrLoadEvent = ( e : Event ) => {
142- const xhr : XMLHttpRequest = e . target as XMLHttpRequest ;
143- const xhrDetails : XhrDetails = this . xhrMap . get ( xhr ) as XhrDetails ;
144- if ( xhrDetails ) {
145- const endTimee = epochTime ( ) ;
146- xhrDetails . trace ! . end_time = endTimee ;
147- xhrDetails . trace ! . subsegments ! [ 0 ] . end_time = endTimee ;
148- xhrDetails . trace ! . subsegments ! [ 0 ] . http ! . response = {
149- status : xhr . status
146+ const request = e . target as XMLHttpRequest ;
147+ const details = this . map . get ( request ) ;
148+ if ( details ) {
149+ const endTime = epochTime ( ) ;
150+ details . trace ! . end_time = endTime ;
151+ details . trace ! . subsegments ! [ 0 ] . end_time = endTime ;
152+ details . trace ! . subsegments ! [ 0 ] . http ! . response = {
153+ status : request . status
150154 } ;
151155
152- if ( is429 ( xhr . status ) ) {
153- xhrDetails . trace ! . subsegments ! [ 0 ] . throttle = true ;
154- xhrDetails . trace ! . throttle = true ;
155- } else if ( is4xx ( xhr . status ) ) {
156- xhrDetails . trace ! . subsegments ! [ 0 ] . error = true ;
157- xhrDetails . trace ! . error = true ;
158- } else if ( is5xx ( xhr . status ) ) {
159- xhrDetails . trace ! . subsegments ! [ 0 ] . fault = true ;
160- xhrDetails . trace ! . fault = true ;
156+ if ( is429 ( request . status ) ) {
157+ details . trace ! . subsegments ! [ 0 ] . throttle = true ;
158+ details . trace ! . throttle = true ;
159+ } else if ( is4xx ( request . status ) ) {
160+ details . trace ! . subsegments ! [ 0 ] . error = true ;
161+ details . trace ! . error = true ;
162+ } else if ( is5xx ( request . status ) ) {
163+ details . trace ! . subsegments ! [ 0 ] . fault = true ;
164+ details . trace ! . fault = true ;
161165 }
162166
163- const clStr = xhr . getResponseHeader ( 'Content-Length' ) ;
167+ const clStr = request . getResponseHeader ( 'Content-Length' ) ;
164168 const cl = clStr ? parseInt ( clStr , 10 ) : NaN ;
165169 if ( ! isNaN ( cl ) ) {
166- xhrDetails . trace ! . subsegments ! [ 0 ] . http ! . response . content_length =
170+ details . trace ! . subsegments ! [ 0 ] . http ! . response . content_length =
167171 cl ;
168172 }
169- this . recordTraceEvent ( xhrDetails . trace ! ) ;
170- this . recordHttpEventWithResponse ( xhrDetails , xhr ) ;
173+ this . recordTraceEvent ( details . trace ! ) ;
174+ this . recordHttpEventWithResponse ( details , request ) ;
171175 }
172176 } ;
173177
174178 private handleXhrErrorEvent = ( e : Event ) => {
175- const xhr : XMLHttpRequest = e . target as XMLHttpRequest ;
176- const xhrDetails = this . xhrMap . get ( xhr ) ;
179+ const request = e . target as XMLHttpRequest ;
180+ const details = this . map . get ( request ) ;
177181 const errorName = 'XMLHttpRequest error' ;
178- const errorMessage : string = xhr . statusText
179- ? xhr . status . toString ( ) + ': ' + xhr . statusText
180- : xhr . status . toString ( ) ;
181- if ( xhrDetails ) {
182+ const errorMessage : string = request . statusText
183+ ? request . status . toString ( ) + ': ' + request . statusText
184+ : request . status . toString ( ) ;
185+ if ( details ) {
182186 const endTime = epochTime ( ) ;
183187 // Guidance from X-Ray documentation:
184188 // > Record errors in segments when your application returns an
185189 // > error to the user, and in subsegments when a downstream call
186190 // > returns an error.
187- xhrDetails . trace ! . fault = true ;
188- xhrDetails . trace ! . end_time = endTime ;
189- xhrDetails . trace ! . subsegments ! [ 0 ] . end_time = endTime ;
190- xhrDetails . trace ! . subsegments ! [ 0 ] . fault = true ;
191- xhrDetails . trace ! . subsegments ! [ 0 ] . cause = {
191+ details . trace ! . fault = true ;
192+ details . trace ! . end_time = endTime ;
193+ details . trace ! . subsegments ! [ 0 ] . end_time = endTime ;
194+ details . trace ! . subsegments ! [ 0 ] . fault = true ;
195+ details . trace ! . subsegments ! [ 0 ] . cause = {
192196 exceptions : [
193197 {
194198 type : errorName ,
195199 message : errorMessage
196200 }
197201 ]
198202 } ;
199- this . recordTraceEvent ( xhrDetails . trace ! ) ;
203+ this . recordTraceEvent ( details . trace ! ) ;
200204 this . recordHttpEventWithError (
201- xhrDetails ,
205+ details ,
206+ request ,
202207 new XhrError ( errorMessage )
203208 ) ;
204209 }
205210 } ;
206211
207212 private handleXhrAbortEvent = ( e : Event ) => {
208- const xhr : XMLHttpRequest = e . target as XMLHttpRequest ;
209- const xhrDetails = this . xhrMap . get ( xhr ) ;
210- const errorName = 'XMLHttpRequest abort' ;
211- this . handleXhrDetailsOnError ( xhrDetails , errorName ) ;
213+ const request = e . target as XMLHttpRequest ;
214+ const details = this . map . get ( request ) ;
215+ if ( details ) {
216+ this . handleXhrDetailsOnError (
217+ details ,
218+ request ,
219+ 'XMLHttpRequest abort'
220+ ) ;
221+ }
212222 } ;
213223
214224 private handleXhrTimeoutEvent = ( e : Event ) => {
215- const xhr : XMLHttpRequest = e . target as XMLHttpRequest ;
216- const xhrDetails = this . xhrMap . get ( xhr ) ;
225+ const request = e . target as XMLHttpRequest ;
226+ const details = this . map . get ( request ) ;
217227 const errorName = 'XMLHttpRequest timeout' ;
218- this . handleXhrDetailsOnError ( xhrDetails , errorName ) ;
228+ this . handleXhrDetailsOnError ( details , request , errorName ) ;
219229 } ;
220230
221231 private handleXhrDetailsOnError (
222- xhrDetails : XhrDetails | undefined ,
232+ details : XhrDetails | undefined ,
233+ request : XMLHttpRequest ,
223234 errorName : string
224235 ) {
225- if ( xhrDetails ) {
236+ if ( details ) {
226237 const endTime = epochTime ( ) ;
227- xhrDetails . trace ! . end_time = endTime ;
228- xhrDetails . trace ! . subsegments ! [ 0 ] . end_time = endTime ;
229- xhrDetails . trace ! . subsegments ! [ 0 ] . error = true ;
230- xhrDetails . trace ! . subsegments ! [ 0 ] . cause = {
238+ details . trace ! . end_time = endTime ;
239+ details . trace ! . subsegments ! [ 0 ] . end_time = endTime ;
240+ details . trace ! . subsegments ! [ 0 ] . error = true ;
241+ details . trace ! . subsegments ! [ 0 ] . cause = {
231242 exceptions : [
232243 {
233244 type : errorName
234245 }
235246 ]
236247 } ;
237- this . recordTraceEvent ( xhrDetails . trace ! ) ;
238- this . recordHttpEventWithError ( xhrDetails , errorName ) ;
248+ this . recordTraceEvent ( details . trace ! ) ;
249+ this . recordHttpEventWithError ( details , request , errorName ) ;
239250 }
240251 }
241252
@@ -244,30 +255,36 @@ export class XhrPlugin extends MonkeyPatched<XMLHttpRequest, 'send' | 'open'> {
244255 }
245256
246257 private recordHttpEventWithResponse (
247- xhrDetails : XhrDetails ,
248- xhr : XMLHttpRequest
258+ details : XhrDetails ,
259+ request : XMLHttpRequest
249260 ) {
261+ this . map . delete ( request ) ;
250262 const httpEvent : HttpEvent = {
251263 version : '1.0.0' ,
252- request : { method : xhrDetails . method , url : xhrDetails . url } ,
253- response : { status : xhr . status , statusText : xhr . statusText }
264+ request : { method : details . method , url : details . url } ,
265+ response : {
266+ status : request . status ,
267+ statusText : request . statusText
268+ }
254269 } ;
255270 if ( this . isTracingEnabled ( ) ) {
256- httpEvent . trace_id = xhrDetails . trace ! . trace_id ;
257- httpEvent . segment_id = xhrDetails . trace ! . subsegments ! [ 0 ] . id ;
271+ httpEvent . trace_id = details . trace ! . trace_id ;
272+ httpEvent . segment_id = details . trace ! . subsegments ! [ 0 ] . id ;
258273 }
259- if ( this . config . recordAllRequests || ! this . statusOk ( xhr . status ) ) {
274+ if ( this . config . recordAllRequests || ! this . statusOk ( request . status ) ) {
260275 this . context . record ( HTTP_EVENT_TYPE , httpEvent ) ;
261276 }
262277 }
263278
264279 private recordHttpEventWithError (
265- xhrDetails : XhrDetails ,
280+ details : XhrDetails ,
281+ request : XMLHttpRequest ,
266282 error : Error | string | number | boolean | undefined | null
267283 ) {
284+ this . map . delete ( request ) ;
268285 const httpEvent : HttpEvent = {
269286 version : '1.0.0' ,
270- request : { method : xhrDetails . method , url : xhrDetails . url } ,
287+ request : { method : details . method , url : details . url } ,
271288 error : errorEventToJsErrorEvent (
272289 {
273290 type : 'error' ,
@@ -277,8 +294,8 @@ export class XhrPlugin extends MonkeyPatched<XMLHttpRequest, 'send' | 'open'> {
277294 )
278295 } ;
279296 if ( this . isTracingEnabled ( ) ) {
280- httpEvent . trace_id = xhrDetails . trace ! . trace_id ;
281- httpEvent . segment_id = xhrDetails . trace ! . subsegments ! [ 0 ] . id ;
297+ httpEvent . trace_id = details . trace ! . trace_id ;
298+ httpEvent . segment_id = details . trace ! . subsegments ! [ 0 ] . id ;
282299 }
283300 this . context . record ( HTTP_EVENT_TYPE , httpEvent ) ;
284301 }
@@ -293,20 +310,20 @@ export class XhrPlugin extends MonkeyPatched<XMLHttpRequest, 'send' | 'open'> {
293310 }
294311 }
295312
296- private initializeTrace = ( xhrDetails : XhrDetails ) => {
313+ private initializeTrace = ( details : XhrDetails ) => {
297314 const startTime = epochTime ( ) ;
298- xhrDetails . trace = createXRayTraceEvent (
315+ details . trace = createXRayTraceEvent (
299316 this . config . logicalServiceName ,
300317 startTime
301318 ) ;
302- xhrDetails . trace . subsegments ! . push (
319+ details . trace . subsegments ! . push (
303320 createXRaySubsegment (
304- requestInfoToHostname ( xhrDetails . url ) ,
321+ requestInfoToHostname ( details . url ) ,
305322 startTime ,
306323 {
307324 request : {
308- method : xhrDetails . method ,
309- url : xhrDetails . url ,
325+ method : details . method ,
326+ url : details . url ,
310327 traced : true
311328 }
312329 }
@@ -318,8 +335,8 @@ export class XhrPlugin extends MonkeyPatched<XMLHttpRequest, 'send' | 'open'> {
318335 const self = this ;
319336 return ( original : any ) => {
320337 return function ( this : XMLHttpRequest ) : void {
321- const xhrDetails = self . xhrMap . get ( this ) ;
322- if ( xhrDetails ) {
338+ const details = self . map . get ( this ) ;
339+ if ( details ) {
323340 this . addEventListener ( 'load' , self . handleXhrLoadEvent ) ;
324341 this . addEventListener ( 'error' , self . handleXhrErrorEvent ) ;
325342 this . addEventListener ( 'abort' , self . handleXhrAbortEvent ) ;
@@ -328,7 +345,7 @@ export class XhrPlugin extends MonkeyPatched<XMLHttpRequest, 'send' | 'open'> {
328345 self . handleXhrTimeoutEvent
329346 ) ;
330347
331- self . initializeTrace ( xhrDetails ) ;
348+ self . initializeTrace ( details ) ;
332349
333350 if (
334351 ! self . isSyntheticsUA &&
@@ -339,8 +356,8 @@ export class XhrPlugin extends MonkeyPatched<XMLHttpRequest, 'send' | 'open'> {
339356 this . setRequestHeader (
340357 X_AMZN_TRACE_ID ,
341358 getAmznTraceIdHeaderValue (
342- xhrDetails . trace ! . trace_id ,
343- xhrDetails . trace ! . subsegments ! [ 0 ] . id
359+ details . trace ! . trace_id ,
360+ details . trace ! . subsegments ! [ 0 ] . id
344361 )
345362 ) ;
346363 }
@@ -360,7 +377,7 @@ export class XhrPlugin extends MonkeyPatched<XMLHttpRequest, 'send' | 'open'> {
360377 async : boolean
361378 ) : void {
362379 if ( isUrlAllowed ( url , self . config ) ) {
363- self . xhrMap . set ( this , { url, method, async } ) ;
380+ self . map . set ( this , { url, method, async } ) ;
364381 }
365382 return original . apply ( this , arguments ) ;
366383 } ;
0 commit comments