@@ -95,18 +95,22 @@ 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
100100 constructor ( config ?: PartialHttpPluginConfig ) {
101101 super ( XHR_PLUGIN_ID ) ;
102102 this . config = { ...defaultConfig , ...config } ;
103- this . xhrMap = new Map < XMLHttpRequest , XhrDetails > ( ) ;
103+ this . map = new Map < XMLHttpRequest , XhrDetails > ( ) ;
104104 }
105105
106106 protected onload ( ) : void {
107107 this . enable ( ) ;
108108 }
109109
110+ get cacheSize ( ) {
111+ return this . map . size ;
112+ }
113+
110114 protected get patches ( ) {
111115 return [
112116 {
@@ -135,103 +139,110 @@ export class XhrPlugin extends MonkeyPatched<XMLHttpRequest, 'send' | 'open'> {
135139 } ;
136140
137141 private handleXhrLoadEvent = ( e : Event ) => {
138- const xhr : XMLHttpRequest = e . target as XMLHttpRequest ;
139- const xhrDetails : XhrDetails = this . xhrMap . get ( xhr ) as XhrDetails ;
140- if ( xhrDetails ) {
141- const endTimee = epochTime ( ) ;
142- xhrDetails . trace ! . end_time = endTimee ;
143- xhrDetails . trace ! . subsegments ! [ 0 ] . end_time = endTimee ;
144- xhrDetails . trace ! . subsegments ! [ 0 ] . http ! . response = {
145- status : xhr . status
142+ const request = e . target as XMLHttpRequest ;
143+ const details = this . map . get ( request ) ;
144+ if ( details ) {
145+ const endTime = epochTime ( ) ;
146+ details . trace ! . end_time = endTime ;
147+ details . trace ! . subsegments ! [ 0 ] . end_time = endTime ;
148+ details . trace ! . subsegments ! [ 0 ] . http ! . response = {
149+ status : request . status
146150 } ;
147151
148- if ( is429 ( xhr . status ) ) {
149- xhrDetails . trace ! . subsegments ! [ 0 ] . throttle = true ;
150- xhrDetails . trace ! . throttle = true ;
151- } else if ( is4xx ( xhr . status ) ) {
152- xhrDetails . trace ! . subsegments ! [ 0 ] . error = true ;
153- xhrDetails . trace ! . error = true ;
154- } else if ( is5xx ( xhr . status ) ) {
155- xhrDetails . trace ! . subsegments ! [ 0 ] . fault = true ;
156- xhrDetails . trace ! . fault = true ;
152+ if ( is429 ( request . status ) ) {
153+ details . trace ! . subsegments ! [ 0 ] . throttle = true ;
154+ details . trace ! . throttle = true ;
155+ } else if ( is4xx ( request . status ) ) {
156+ details . trace ! . subsegments ! [ 0 ] . error = true ;
157+ details . trace ! . error = true ;
158+ } else if ( is5xx ( request . status ) ) {
159+ details . trace ! . subsegments ! [ 0 ] . fault = true ;
160+ details . trace ! . fault = true ;
157161 }
158162
159- const clStr = xhr . getResponseHeader ( 'Content-Length' ) ;
163+ const clStr = request . getResponseHeader ( 'Content-Length' ) ;
160164 const cl = clStr ? parseInt ( clStr , 10 ) : NaN ;
161165 if ( ! isNaN ( cl ) ) {
162- xhrDetails . trace ! . subsegments ! [ 0 ] . http ! . response . content_length =
166+ details . trace ! . subsegments ! [ 0 ] . http ! . response . content_length =
163167 cl ;
164168 }
165- this . recordTraceEvent ( xhrDetails . trace ! ) ;
166- this . recordHttpEventWithResponse ( xhrDetails , xhr ) ;
169+ this . recordTraceEvent ( details . trace ! ) ;
170+ this . recordHttpEventWithResponse ( details , request ) ;
167171 }
168172 } ;
169173
170174 private handleXhrErrorEvent = ( e : Event ) => {
171- const xhr : XMLHttpRequest = e . target as XMLHttpRequest ;
172- const xhrDetails = this . xhrMap . get ( xhr ) ;
175+ const request = e . target as XMLHttpRequest ;
176+ const details = this . map . get ( request ) ;
173177 const errorName = 'XMLHttpRequest error' ;
174- const errorMessage : string = xhr . statusText
175- ? xhr . status . toString ( ) + ': ' + xhr . statusText
176- : xhr . status . toString ( ) ;
177- if ( xhrDetails ) {
178+ const errorMessage : string = request . statusText
179+ ? request . status . toString ( ) + ': ' + request . statusText
180+ : request . status . toString ( ) ;
181+ if ( details ) {
178182 const endTime = epochTime ( ) ;
179183 // Guidance from X-Ray documentation:
180184 // > Record errors in segments when your application returns an
181185 // > error to the user, and in subsegments when a downstream call
182186 // > returns an error.
183- xhrDetails . trace ! . fault = true ;
184- xhrDetails . trace ! . end_time = endTime ;
185- xhrDetails . trace ! . subsegments ! [ 0 ] . end_time = endTime ;
186- xhrDetails . trace ! . subsegments ! [ 0 ] . fault = true ;
187- xhrDetails . trace ! . subsegments ! [ 0 ] . cause = {
187+ details . trace ! . fault = true ;
188+ details . trace ! . end_time = endTime ;
189+ details . trace ! . subsegments ! [ 0 ] . end_time = endTime ;
190+ details . trace ! . subsegments ! [ 0 ] . fault = true ;
191+ details . trace ! . subsegments ! [ 0 ] . cause = {
188192 exceptions : [
189193 {
190194 type : errorName ,
191195 message : errorMessage
192196 }
193197 ]
194198 } ;
195- this . recordTraceEvent ( xhrDetails . trace ! ) ;
199+ this . recordTraceEvent ( details . trace ! ) ;
196200 this . recordHttpEventWithError (
197- xhrDetails ,
201+ details ,
202+ request ,
198203 new XhrError ( errorMessage )
199204 ) ;
200205 }
201206 } ;
202207
203208 private handleXhrAbortEvent = ( e : Event ) => {
204- const xhr : XMLHttpRequest = e . target as XMLHttpRequest ;
205- const xhrDetails = this . xhrMap . get ( xhr ) ;
206- const errorName = 'XMLHttpRequest abort' ;
207- this . handleXhrDetailsOnError ( xhrDetails , errorName ) ;
209+ const request = e . target as XMLHttpRequest ;
210+ const details = this . map . get ( request ) ;
211+ if ( details ) {
212+ this . handleXhrDetailsOnError (
213+ details ,
214+ request ,
215+ 'XMLHttpRequest abort'
216+ ) ;
217+ }
208218 } ;
209219
210220 private handleXhrTimeoutEvent = ( e : Event ) => {
211- const xhr : XMLHttpRequest = e . target as XMLHttpRequest ;
212- const xhrDetails = this . xhrMap . get ( xhr ) ;
221+ const request = e . target as XMLHttpRequest ;
222+ const details = this . map . get ( request ) ;
213223 const errorName = 'XMLHttpRequest timeout' ;
214- this . handleXhrDetailsOnError ( xhrDetails , errorName ) ;
224+ this . handleXhrDetailsOnError ( details , request , errorName ) ;
215225 } ;
216226
217227 private handleXhrDetailsOnError (
218- xhrDetails : XhrDetails | undefined ,
228+ details : XhrDetails | undefined ,
229+ request : XMLHttpRequest ,
219230 errorName : string
220231 ) {
221- if ( xhrDetails ) {
232+ if ( details ) {
222233 const endTime = epochTime ( ) ;
223- xhrDetails . trace ! . end_time = endTime ;
224- xhrDetails . trace ! . subsegments ! [ 0 ] . end_time = endTime ;
225- xhrDetails . trace ! . subsegments ! [ 0 ] . error = true ;
226- xhrDetails . trace ! . subsegments ! [ 0 ] . cause = {
234+ details . trace ! . end_time = endTime ;
235+ details . trace ! . subsegments ! [ 0 ] . end_time = endTime ;
236+ details . trace ! . subsegments ! [ 0 ] . error = true ;
237+ details . trace ! . subsegments ! [ 0 ] . cause = {
227238 exceptions : [
228239 {
229240 type : errorName
230241 }
231242 ]
232243 } ;
233- this . recordTraceEvent ( xhrDetails . trace ! ) ;
234- this . recordHttpEventWithError ( xhrDetails , errorName ) ;
244+ this . recordTraceEvent ( details . trace ! ) ;
245+ this . recordHttpEventWithError ( details , request , errorName ) ;
235246 }
236247 }
237248
@@ -240,33 +251,40 @@ export class XhrPlugin extends MonkeyPatched<XMLHttpRequest, 'send' | 'open'> {
240251 }
241252
242253 private recordHttpEventWithResponse (
243- xhrDetails : XhrDetails ,
244- xhr : XMLHttpRequest
254+ details : XhrDetails ,
255+ request : XMLHttpRequest
245256 ) {
246- if ( this . config . recordAllRequests || ! this . statusOk ( xhr . status ) ) {
247- this . context . record ( HTTP_EVENT_TYPE , {
248- version : '1.0.0' ,
249- request : { method : xhrDetails . method , url : xhrDetails . url } ,
250- response : { status : xhr . status , statusText : xhr . statusText }
251- } ) ;
257+ this . map . delete ( request ) ;
258+ const httpEvent : HttpEvent = {
259+ version : '1.0.0' ,
260+ request : { method : details . method , url : details . url } ,
261+ response : {
262+ status : request . status ,
263+ statusText : request . statusText
264+ }
265+ } ;
266+ if ( this . config . recordAllRequests || ! this . statusOk ( request . status ) ) {
267+ this . context . record ( HTTP_EVENT_TYPE , httpEvent ) ;
252268 }
253269 }
254270
255271 private recordHttpEventWithError (
256- xhrDetails : XhrDetails ,
272+ details : XhrDetails ,
273+ request : XMLHttpRequest ,
257274 error : Error | string | number | boolean | undefined | null
258275 ) {
276+ this . map . delete ( request ) ;
259277 const httpEvent : HttpEvent = {
260278 version : '1.0.0' ,
261- request : { method : xhrDetails . method , url : xhrDetails . url }
279+ request : { method : details . method , url : details . url } ,
280+ error : errorEventToJsErrorEvent (
281+ {
282+ type : 'error' ,
283+ error
284+ } as ErrorEvent ,
285+ this . config . stackTraceLength
286+ )
262287 } ;
263- httpEvent . error = errorEventToJsErrorEvent (
264- {
265- type : 'error' ,
266- error
267- } as ErrorEvent ,
268- this . config . stackTraceLength
269- ) ;
270288 this . context . record ( HTTP_EVENT_TYPE , httpEvent ) ;
271289 }
272290
@@ -276,20 +294,20 @@ export class XhrPlugin extends MonkeyPatched<XMLHttpRequest, 'send' | 'open'> {
276294 }
277295 }
278296
279- private initializeTrace = ( xhrDetails : XhrDetails ) => {
297+ private initializeTrace = ( details : XhrDetails ) => {
280298 const startTime = epochTime ( ) ;
281- xhrDetails . trace = createXRayTraceEvent (
299+ details . trace = createXRayTraceEvent (
282300 this . config . logicalServiceName ,
283301 startTime
284302 ) ;
285- xhrDetails . trace . subsegments ! . push (
303+ details . trace . subsegments ! . push (
286304 createXRaySubsegment (
287- requestInfoToHostname ( xhrDetails . url ) ,
305+ requestInfoToHostname ( details . url ) ,
288306 startTime ,
289307 {
290308 request : {
291- method : xhrDetails . method ,
292- url : xhrDetails . url ,
309+ method : details . method ,
310+ url : details . url ,
293311 traced : true
294312 }
295313 }
@@ -301,8 +319,8 @@ export class XhrPlugin extends MonkeyPatched<XMLHttpRequest, 'send' | 'open'> {
301319 const self = this ;
302320 return ( original : any ) => {
303321 return function ( this : XMLHttpRequest ) : void {
304- const xhrDetails = self . xhrMap . get ( this ) ;
305- if ( xhrDetails ) {
322+ const details = self . map . get ( this ) ;
323+ if ( details ) {
306324 this . addEventListener ( 'load' , self . handleXhrLoadEvent ) ;
307325 this . addEventListener ( 'error' , self . handleXhrErrorEvent ) ;
308326 this . addEventListener ( 'abort' , self . handleXhrAbortEvent ) ;
@@ -311,7 +329,7 @@ export class XhrPlugin extends MonkeyPatched<XMLHttpRequest, 'send' | 'open'> {
311329 self . handleXhrTimeoutEvent
312330 ) ;
313331
314- self . initializeTrace ( xhrDetails ) ;
332+ self . initializeTrace ( details ) ;
315333
316334 if (
317335 self . isTracingEnabled ( ) &&
@@ -321,8 +339,8 @@ export class XhrPlugin extends MonkeyPatched<XMLHttpRequest, 'send' | 'open'> {
321339 this . setRequestHeader (
322340 X_AMZN_TRACE_ID ,
323341 getAmznTraceIdHeaderValue (
324- xhrDetails . trace ! . trace_id ,
325- xhrDetails . trace ! . subsegments ! [ 0 ] . id
342+ details . trace ! . trace_id ,
343+ details . trace ! . subsegments ! [ 0 ] . id
326344 )
327345 ) ;
328346 }
@@ -342,7 +360,7 @@ export class XhrPlugin extends MonkeyPatched<XMLHttpRequest, 'send' | 'open'> {
342360 async : boolean
343361 ) : void {
344362 if ( isUrlAllowed ( url , self . config ) ) {
345- self . xhrMap . set ( this , { url, method, async } ) ;
363+ self . map . set ( this , { url, method, async } ) ;
346364 }
347365 return original . apply ( this , arguments ) ;
348366 } ;
0 commit comments