From 6aa2ecebd91fba05c395ac59a8e0346401713b59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Og=C3=B3rek?= Date: Mon, 8 Jun 2020 13:10:38 +0200 Subject: [PATCH] Change XHR instrumentation ordering (#2643) --- CHANGELOG.md | 1 + packages/utils/src/instrument.ts | 53 +++++++++++++++++++------------- 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d14bf0d4c9af..c39c9ecb43c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - "You miss 100 percent of the chances you don't take. — Wayne Gretzky" — Michael Scott - [react] feat: Add @sentry/react package (#2631) +- [browser] Change XHR instrumentation order to handle `onreadystatechange` breadcrumbs correctly (#2643) ## 5.16.1 diff --git a/packages/utils/src/instrument.ts b/packages/utils/src/instrument.ts index f4880b5fa229..6348111563c4 100644 --- a/packages/utils/src/instrument.ts +++ b/packages/utils/src/instrument.ts @@ -218,35 +218,19 @@ function instrumentXHR(): void { fill(xhrproto, 'open', function(originalOpen: () => void): () => void { return function(this: SentryWrappedXMLHttpRequest, ...args: any[]): void { + const xhr = this; // tslint:disable-line:no-this-assignment const url = args[1]; - this.__sentry_xhr__ = { + xhr.__sentry_xhr__ = { method: isString(args[0]) ? args[0].toUpperCase() : args[0], url: args[1], }; // if Sentry key appears in URL, don't capture it as a request - if (isString(url) && this.__sentry_xhr__.method === 'POST' && url.match(/sentry_key/)) { - this.__sentry_own_request__ = true; + if (isString(url) && xhr.__sentry_xhr__.method === 'POST' && url.match(/sentry_key/)) { + xhr.__sentry_own_request__ = true; } - return originalOpen.apply(this, args); - }; - }); - - fill(xhrproto, 'send', function(originalSend: () => void): () => void { - return function(this: SentryWrappedXMLHttpRequest, ...args: any[]): void { - const xhr = this; // tslint:disable-line:no-this-assignment - const commonHandlerData = { - args, - startTimestamp: Date.now(), - xhr, - }; - - triggerHandlers('xhr', { - ...commonHandlerData, - }); - - xhr.addEventListener('readystatechange', function(): void { + const onreadystatechangeHandler = function(): void { if (xhr.readyState === 4) { try { // touching statusCode in some platforms throws @@ -258,10 +242,35 @@ function instrumentXHR(): void { /* do nothing */ } triggerHandlers('xhr', { - ...commonHandlerData, + args, endTimestamp: Date.now(), + startTimestamp: Date.now(), + xhr, }); } + }; + + if ('onreadystatechange' in xhr && typeof xhr.onreadystatechange === 'function') { + fill(xhr, 'onreadystatechange', function(original: WrappedFunction): Function { + return function(...readyStateArgs: any[]): void { + onreadystatechangeHandler(); + return original.apply(xhr, readyStateArgs); + }; + }); + } else { + xhr.addEventListener('readystatechange', onreadystatechangeHandler); + } + + return originalOpen.apply(xhr, args); + }; + }); + + fill(xhrproto, 'send', function(originalSend: () => void): () => void { + return function(this: SentryWrappedXMLHttpRequest, ...args: any[]): void { + triggerHandlers('xhr', { + args, + startTimestamp: Date.now(), + xhr: this, }); return originalSend.apply(this, args);