Skip to content

Commit

Permalink
gracefully degrade an XMLHTTPRequest with undefined function context
Browse files Browse the repository at this point in the history
  • Loading branch information
Dan Skinner committed Jan 30, 2024
1 parent 159e236 commit 9b222a8
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 8 deletions.
10 changes: 8 additions & 2 deletions packages/plugin-network-breadcrumbs/network-breadcrumbs.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ module.exports = (_ignoredUrls = [], win = window) => {

const originalOpen = win.XMLHttpRequest.prototype.open
win.XMLHttpRequest.prototype.open = function open (method, url) {
trackedRequests.set(this, { method, url })
// it's possible for `this` to be `undefined`, which is not a valid key for a WeakMap
if (this) {
trackedRequests.set(this, { method, url })
}
originalOpen.apply(this, arguments)
}

Expand All @@ -50,7 +53,10 @@ module.exports = (_ignoredUrls = [], win = window) => {

this.addEventListener('load', load)
this.addEventListener('error', error)
requestHandlers.set(this, { load, error })
// it's possible for `this` to be `undefined`, which is not a valid key for a WeakMap
if (this) {
requestHandlers.set(this, { load, error })
}
}

originalSend.apply(this, arguments)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,20 @@ class XMLHttpRequest {

send (fail: boolean, status: number | null = null) {
if (fail) {
this._listeners.error.map(fn => fn())
this?._listeners.error.map(fn => fn())
} else {
this.status = status
this._listeners.load.map(fn => fn())
this?._listeners.load.map(fn => fn())
}
}

addEventListener (evt: 'load'| 'error', listener: () => void) {
this._listeners[evt].push(listener)
this?._listeners[evt].push(listener)
}

removeEventListener (evt: 'load'| 'error', listener: () => void) {
for (let i = this._listeners[evt].length - 1; i >= 0; i--) {
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
if (listener.name === this._listeners[evt][i].name) delete this._listeners[evt][i]
for (let i = this?._listeners?.[evt]?.length ?? 0 - 1; i >= 0; i--) {
if (listener.name === this?._listeners?.[evt]?.[i]?.name) delete this?._listeners[evt][i]
}
}
}
Expand Down Expand Up @@ -205,6 +204,22 @@ describe('plugin: network breadcrumbs', () => {
}))
})

it('should gracefully degrade an XMLHTTPRequest with undefined function context', () => {
const window = { XMLHttpRequest, WeakMap } as unknown as Window & typeof globalThis

p = plugin([], window)
const client = new Client({ apiKey: 'aaaa-aaaa-aaaa-aaaa', plugins: [p] })

const request = new window.XMLHttpRequest() as unknown as XMLHttpRequest
const open = request.open
const send = request.send

open('GET', 'https://another-domain.xyz/')
send(true)

expect(client._breadcrumbs.length).toBe(0)
})

it('should not leave a breadcrumb for request to bugsnag notify endpoint', () => {
const window = { XMLHttpRequest, WeakMap } as unknown as Window & typeof globalThis

Expand Down

0 comments on commit 9b222a8

Please sign in to comment.