From d82d91a8febd0c138b7fa476315459f12fb37e7e Mon Sep 17 00:00:00 2001 From: Bastien Caudan Date: Mon, 19 Apr 2021 11:36:54 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20fallback=20to=20xhr=20when=20sen?= =?UTF-8?q?dBeacon=20throws=20(#796)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 🐛 fallback to xhr when sendBeacon throws * 🐛 avoid a loop of reporting errors if beacon systematically throws --- packages/core/src/transport/transport.spec.ts | 11 ++++++++++ packages/core/src/transport/transport.ts | 20 +++++++++++++++---- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/packages/core/src/transport/transport.spec.ts b/packages/core/src/transport/transport.spec.ts index 1865fe91e3..bd06d80213 100644 --- a/packages/core/src/transport/transport.spec.ts +++ b/packages/core/src/transport/transport.spec.ts @@ -53,6 +53,17 @@ describe('request', () => { expect(navigator.sendBeacon).toHaveBeenCalled() expect(server.requests.length).toEqual(1) }) + + it('should fallback to xhr when sendBeacon throws', () => { + spyOn(navigator, 'sendBeacon').and.callFake(() => { + throw new TypeError() + }) + + request.send('{"foo":"bar1"}\n{"foo":"bar2"}', 10) + + expect(navigator.sendBeacon).toHaveBeenCalled() + expect(server.requests.length).toEqual(1) + }) }) describe('batch', () => { diff --git a/packages/core/src/transport/transport.ts b/packages/core/src/transport/transport.ts index a059015b78..dfb251c381 100644 --- a/packages/core/src/transport/transport.ts +++ b/packages/core/src/transport/transport.ts @@ -1,7 +1,7 @@ import { Context } from '../tools/context' import { getTimeStamp, relativeNow } from '../tools/timeUtils' import { addEventListener, DOM_EVENT, jsonStringify, noop, objectValues } from '../tools/utils' -import { monitor } from '../domain/internalMonitoring' +import { monitor, addErrorToMonitoringBatch } from '../domain/internalMonitoring' // https://en.wikipedia.org/wiki/UTF-8 const HAS_MULTI_BYTES_CHARACTERS = /[^\u0000-\u007F]/ @@ -20,9 +20,13 @@ export class HttpRequest { send(data: string | FormData, size: number) { const url = this.withBatchTime ? addBatchTime(this.endpointUrl) : this.endpointUrl if (navigator.sendBeacon && size < this.bytesLimit) { - const isQueued = navigator.sendBeacon(url, data) - if (isQueued) { - return + try { + const isQueued = navigator.sendBeacon(url, data) + if (isQueued) { + return + } + } catch (e) { + reportBeaconError(e) } } const request = new XMLHttpRequest() @@ -37,6 +41,14 @@ function addBatchTime(url: string) { )}` } +let hasReportedBeaconError = false +function reportBeaconError(e: unknown) { + if (!hasReportedBeaconError) { + hasReportedBeaconError = true + addErrorToMonitoringBatch(e) + } +} + export class Batch { private pushOnlyBuffer: string[] = [] private upsertBuffer: { [key: string]: string } = {}