airbrake / airbrake-js

Airbrake JavaScript Notifier
https://airbrake.io
MIT License
422 stars 139 forks source link

Cross-Fetch dep is trying to use XHR in service-worker context. #1209

Open ntinkler-calendly opened 2 years ago

ntinkler-calendly commented 2 years ago

🐞 bug report

Affected Package

"@airbrake/browser": "^2.1.7"

depends on cross-fetch: ^3.0.4

Is this a regression?

I'm not sure. There is a 2018 ticket that implies that at one point Airbrake was working in service workers, but I cannot confirm this is the case. https://github.com/airbrake/airbrake-js/issues/398

Description

Cross-fetch is attempting to polyfill fetch with an XHR based implementation in a service worker.

Service workers do not expose XHR (XMLHttpRequest is not defined). They only provide the fetch api.

An example error stack:

"ReferenceError: XMLHttpRequest is not defined
    at chrome-extension://dohbfkgabajhohdidhmhhpfagifoacnk/background.js:5029:25
    at new Promise (<anonymous>)
    at fetch3 (chrome-extension://dohbfkgabajhohdidhmhhpfagifoacnk/background.js:5024:20)
    at Notifier2.request [as _requester] (chrome-extension://dohbfkgabajhohdidhmhhpfagifoacnk/background.js:5125:43)
    at Notifier2._sendNotice (chrome-extension://dohbfkgabajhohdidhmhhpfagifoacnk/background.js:6882:23)
    at Notifier2.notify (chrome-extension://dohbfkgabajhohdidhmhhpfagifoacnk/background.js:6864:23)
    at Notifier2.notify (chrome-extension://dohbfkgabajhohdidhmhhpfagifoacnk/background.js:7435:42)
    at chrome-extension://dohbfkgabajhohdidhmhhpfagifoacnk/background.js:7547:39
    at Generator.next (<anonymous>)
    at chrome-extension://dohbfkgabajhohdidhmhhpfagifoacnk/background.js:43:63"

🔬 Minimal Reproduction

This must be run in a service-worker context. For this issue, I am using a chrome extension targeting manifest v3, with a background script that includes @airbrake/browser

🔥 Exception or Error


"ReferenceError: XMLHttpRequest is not defined
    at chrome-extension://dohbfkgabajhohdidhmhhpfagifoacnk/background.js:5029:25
    at new Promise ()
    at fetch3 (chrome-extension://dohbfkgabajhohdidhmhhpfagifoacnk/background.js:5024:20)
    at Notifier2.request [as _requester] (chrome-extension://dohbfkgabajhohdidhmhhpfagifoacnk/background.js:5125:43)
    at Notifier2._sendNotice (chrome-extension://dohbfkgabajhohdidhmhhpfagifoacnk/background.js:6882:23)
    at Notifier2.notify (chrome-extension://dohbfkgabajhohdidhmhhpfagifoacnk/background.js:6864:23)
    at Notifier2.notify (chrome-extension://dohbfkgabajhohdidhmhhpfagifoacnk/background.js:7435:42)
    at chrome-extension://dohbfkgabajhohdidhmhhpfagifoacnk/background.js:7547:39
    at Generator.next ()
    at chrome-extension://dohbfkgabajhohdidhmhhpfagifoacnk/background.js:43:63"

The example code I am using to generate this error is

import { Notifier } from '@airbrake/browser'

async function createAirbrakeClient() {
  const airbrake = new Notifier({
    projectId: 0123456,
    projectKey: 'some-project-key',
    environment: 'production',
  })
  const test = await airbrake.notify('this is only a test!')
  console.log('Airbrake result - ', test)
}

createAirbrakeClient()

🌍 Your Environment

@airbrake/* version:


"@airbrake/browser": "^2.1.7"
cross-fetch: ^3.0.4

Anything else relevant? I am currently using ESBuild and typescript, both targeting ES2016. However I can reproduce the issue using the build provided from the CDN (https://unpkg.com/@airbrake/browser), so I do not believe this is related to my build environment.

ntinkler-calendly commented 2 years ago

Note - Simply removing the import of cross-fetch results in a working Notifier for the extension service workers

ex:

diff --git a/manifest_v3/node_modules/@airbrake/browser/esm/http_req/fetch.js b/manifest_v3/node_modules/@airbrake/browser/esm/http_req/fetch.js
index 3ead521e..13523f90 100644
--- a/manifest_v3/node_modules/@airbrake/browser/esm/http_req/fetch.js
+++ b/manifest_v3/node_modules/@airbrake/browser/esm/http_req/fetch.js
@@ -1,4 +1,3 @@
-import fetch from 'cross-fetch';
 import Promise from 'promise-polyfill';
 import { errors } from './api';
 var rateLimitReset = 0;

So it is just this one misbehaving dependency that is blocking support for this environment.

dparish commented 1 year ago

Take a look at:

https://github.com/dparish/airbrake-js-lite

I got rid of cross-fetch and the promise Polyfil so it might resolve this for you.