getsentry / sentry-electron

The official Sentry SDK for Electron
https://sentry.io/
MIT License
224 stars 58 forks source link

navigator.mediaDevices is undefined when i using sentry #948

Open 0xlau opened 1 month ago

0xlau commented 1 month ago

Environment

self-hosted (https://develop.sentry.dev/self-hosted/)

Steps to Reproduce

  1. Create Element App
  2. Init Sentry
  3. Call navigator.mediaDevices

Expected Result

navigator.mediaDevices is not undefined.

Actual Result

img_v3_02ck_d8c5883d-61da-4155-847b-0e66bf0362cg

Product Area

Issues

Link

No response

DSN

No response

Version

No response

getsantry[bot] commented 1 month ago

Auto-routing to @getsentry/product-owners-issues for triage ⏲️

AbhiPrasad commented 1 month ago

Hey @0xlau could you share the fullstack trace of the issue? What self-hosted version are you using?

0xlau commented 1 month ago

@AbhiPrasad

Sentry version: 23.7.11b5a9d7

https://sentry.lusun.cn/share/issue/99784c50a8fc4b64ad00804fa4f16e7e/

We found the big problem is Sentry.init. When the program reaches this line of code, the navigator will be modified.

Before Sentry init:

img_v3_02ck_8a8c9ad5-941b-4aa5-949f-cc3e7815565g

After Sentry init:

img_v3_02ck_3529d3a3-80db-4a5a-8820-2062bce75a5g

AbhiPrasad commented 1 month ago

@0xlau are you using the Electron SDK?

From looking at our SDK we don't mutate mediaDevices in anyway:

Electron: https://github.com/search?q=repo%3Agetsentry%2Fsentry-electron+mediaDevices&type=code JS: https://github.com/search?q=repo%3Agetsentry%2Fsentry-javascript+mediaDevices&type=code

navigator usage: https://github.com/search?q=repo%3Agetsentry%2Fsentry-javascript+navigator&type=code

Could you share your Sentry.init call?

I don't think this is Sentry related, is there another library that could affect navigator?

0xlau commented 1 month ago

Yes. We are using the Electron SDK. And we are absolutely sure it's because of Sentry.init, and navigator.mediaDevices is exists before init Sentry. And not only mediaDevices do not exist, all browser api capabilities in navigator no longer exist, including bluetooth, clipboard, etc. 😢

"@sentry/browser": "^8.14.0",
"@sentry/core": "^8.14.0",
"@sentry/electron": "^4.24.0",
"@sentry/react": "^7.116.0",
"@sentry/tracing": "^7.114.0",
"@sentry/vite-plugin": "^2.18.0",

In the Electron main process:

// main.ts
import * as Sentry from '@sentry/electron';

Sentry.init({
   debug: false,
   dsn: "xxxxxx",
   release: `live_desktop@${app.getVersion()}`,
 });

In the Electron renderer process:

import * as Sentry from '@sentry/electron/renderer';
import { init as reactInit } from '@sentry/react';

Sentry.init({
    integrations: [
      Sentry.browserTracingIntegration(),
      Sentry.replayIntegration(),
    ],

    // Set tracesSampleRate to 1.0 to capture 100%
    // of transactions for performance monitoring.
    // We recommend adjusting this value in production
    tracesSampleRate: 1.0,

    // Capture Replay for 10% of all sessions,
    // plus for 100% of sessions with an error
    replaysSessionSampleRate: 0.1,
    replaysOnErrorSampleRate: 1.0,
  },
  reactInit,
);

In Vite Config:

import { sentryVitePlugin } from "@sentry/vite-plugin";
import { version } from '../package.json';

plugins: [
    ...
    sentryVitePlugin({
        org: "yuanze",
        project: "live_desktop",
        url: "https://sentry.lusun.cn/",
        authToken: "xxxx",
        release:{
          name: `live_desktop@${version}`,
        }
      })
]
AbhiPrasad commented 1 month ago

@0xlau you are using both 8.x and 7.x deps of the JS SDK! Please make sure you are not mixing major versions - either stick to 7.x or upgrade to 8.x overall.

And not only mediaDevices do not exist, all browser api capabilities in navigator no longer exist, including bluetooth, clipboard, etc

I tried reproducing this with my electron apps but no luck (on electron sdk 5.2.0 and js sdk 8.16.0)

maybe try those sdk versions out?

otherwise please share a minimal reproduction of this with a sample electron app so we can test further.

AbhiPrasad commented 1 month ago

Going to also transfer this to the electron repo! https://github.com/getsentry/sentry-electron

0xlau commented 1 month ago

I try to migrate to v8.x. But it still does not work about the missing mediaDevices problem.

    "@sentry/browser": "^8.17.0",
    "@sentry/core": "^8.17.0",
    "@sentry/electron": "^5.2.0",
    "@sentry/react": "^8.17.0",
    "@sentry/vite-plugin": "^2.21.0",

But I found that if I run npm run start in the development environment, navigator.mediaDevices exist, but once I package, navigator doesn't exist. And! If I remove Sentry.init, navigator.mediaDevices will exist whether it is the development environment or after packaging.

AbhiPrasad commented 1 month ago

@0xlau are you able to reproduce this in a barebones electron app? That would help us understand what is happening, unfortunately even with your versions + sdk setup I was unable to reproduce.

0xlau commented 1 month ago

@AbhiPrasad Hey 👋, You can download this project to reproduce this issue. min-error-sentry-reproduction.zip

Step 1: Npm install

> npm install

Step 2: Run in dev

Run in dev, mediaDevices is available

> npm run start

Step 3: Package

After package and run .app, mediaDevices is not available

> npm run package

Step 4: remove Sentry.init

// remove this in main.ts
// Sentry.init({
//   debug: false,
//   dsn: '__DSN__',
//   release: `test@${app.getVersion()}`,
// });

Step 5: Try package again

Remove Sentry.init and then package and then run .app, mediaDevices is available

> npm run package
timfish commented 1 month ago

I've managed to reproduce the issue with the supplied reproduction and I think it has something to do with custom protocols but I don't know the exact cause yet.

For now you might be able to work aroud this in two different ways:

Load your renderer content using file:// urls rather than a custom protocol

You can load your source files into the renderers via file: URLs and the custom protocol isn't usually required to do this.

Use "Classic" IPC for Sentry communications

If classic IPC cannot be configured (usually due to bundling), the Sentry SDK reverts to using a custom protocol to communicate between renderers and main process. You can force classic IPC by including Sentrys preload hookup code in the top of your preload file:

preload.ts

import '@sentry/electron/preload';

and then disable the Sentry custom protcol setup with the following init option:

import * as Sentry from '@sentry/electron/main';

Sentry.init({
  dsn: '__DSN__',
  ipcMode: Sentry.IPCMode.Classic, // <- this disables the Sentry custom protocol
});
timfish commented 1 month ago

Yep, confirmed that loading the renderer via file URL in production works around the issue:

    const url = pathToFileURL(
      path.join(__dirname, `../renderer/${MAIN_WINDOW_VITE_NAME}/index.html`),
    );
    mainWindow.loadURL(url.href);
0xlau commented 1 month ago

@timfish @AbhiPrasad

Use "Classic" IPC for Sentry communications

It works fine! I truly appreciate your timely help.