Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PLAT-9731] Fix XHR delivery postReportCallback #1938

Merged
merged 8 commits into from
Mar 13, 2023
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
### Changes

- (react-native) Update bugsnag-android from v5.28.3 to [v5.28.4](https://github.com/bugsnag/bugsnag-android/blob/master/CHANGELOG.md#5284-2023-02-08)
- (delivery-xml-http-request) Ensure delivery errors are passed to the post report callback [#1938](https://github.com/bugsnag/bugsnag-js/pull/1938)

## 7.20.1 (2023-02-08)

Expand Down
22 changes: 17 additions & 5 deletions packages/delivery-xml-http-request/delivery.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
const payload = require('@bugsnag/core/lib/json-payload')

function deliveryFailed (client, body, cb) {
const err = new Error('Event failed to send')
imjoehaines marked this conversation as resolved.
Show resolved Hide resolved
client._logger.error('Event failed to send…', err)
if (body.length > 10e5) {
client._logger.warn(`Event oversized (${(body.length / 10e5).toFixed(2)} MB)`)
}
cb(err)
}

module.exports = (client, win = window) => ({
sendEvent: (event, cb = () => {}) => {
try {
Expand All @@ -11,14 +20,17 @@ module.exports = (client, win = window) => ({
if (req.readyState === win.XMLHttpRequest.DONE) {
const status = req.status
if (status === 0 || status >= 400) {
client._logger.error('Event failed to send…')
if (body.length > 10e5) {
client._logger.warn(`Event oversized (${(body.length / 10e5).toFixed(2)} MB)`)
}
deliveryFailed(client, body, cb)
} else {
cb(null)
}
cb(null)
}
}

req.onerror = function () {
deliveryFailed(client, body, cb)
}
gingerbenw marked this conversation as resolved.
Show resolved Hide resolved

req.open('POST', url)
req.setRequestHeader('Content-Type', 'application/json')
req.setRequestHeader('Bugsnag-Api-Key', event.apiKey || client._config.apiKey)
Expand Down
49 changes: 47 additions & 2 deletions packages/delivery-xml-http-request/test/delivery.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,50 @@ describe('delivery:XMLHttpRequest', () => {
})
})

it('calls back with an error when report sending fails', done => {
const requests: MockXMLHttpRequest[] = []

// mock XMLHttpRequest class
function XMLHttpRequest (this: MockXMLHttpRequest) {
this.method = null
this.url = null
this.data = null
this.headers = {}
this.readyState = null
this.status = 0
requests.push(this)
}
XMLHttpRequest.DONE = 4
XMLHttpRequest.prototype.open = function (method: string, url: string) {
this.method = method
this.url = url
}
XMLHttpRequest.prototype.setRequestHeader = function (key: string, val: string) {
this.headers[key] = val
}
XMLHttpRequest.prototype.send = function (data: string) {
this.data = data
this.readyState = XMLHttpRequest.DONE
this.status = 500 // server error
this.onreadystatechange()
}

const logger = { error: jest.fn(), warn: jest.fn() }
const payload = { events: [] } as unknown as EventDeliveryPayload
const config = {
apiKey: 'aaaaaaaa',
endpoints: { notify: '/echo/' },
redactedKeys: []
}

delivery({ _logger: logger, _config: config } as unknown as Client, { XMLHttpRequest } as unknown as Window).sendEvent(payload, (err: any) => {
const expectedError = new Error('Event failed to send')
expect(err).toStrictEqual(expectedError)
expect(logger.error).toHaveBeenCalledWith('Event failed to send…', expectedError)
done()
})
})

it('logs failures and large payloads', done => {
const requests: MockXMLHttpRequest[] = []

Expand Down Expand Up @@ -101,8 +145,9 @@ describe('delivery:XMLHttpRequest', () => {
const logger = { error: jest.fn(), warn: jest.fn() }

delivery({ _logger: logger, _config: config } as unknown as Client, { XMLHttpRequest } as unknown as Window).sendEvent(payload, (err: any) => {
expect(err).toBe(null)
expect(logger.error).toHaveBeenCalledWith('Event failed to send…')
const expectedError = new Error('Event failed to send')
expect(err).toStrictEqual(expectedError)
expect(logger.error).toHaveBeenCalledWith('Event failed to send…', expectedError)
expect(logger.warn).toHaveBeenCalledWith('Event oversized (1.01 MB)')
done()
})
Expand Down