navigator.mediaDevices is undefined when i using sentry
0xlau opened this issue ยท 13 comments
Environment
self-hosted (https://develop.sentry.dev/self-hosted/)
Steps to Reproduce
- Create Element App
- Init Sentry
- Call navigator.mediaDevices
Expected Result
navigator.mediaDevices is not undefined.
Actual Result
Product Area
Issues
Link
No response
DSN
No response
Version
No response
Hey @0xlau could you share the fullstack trace of the issue? What self-hosted version are you using?
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:
After Sentry init:
@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
?
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}`,
}
})
]
@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.
Going to also transfer this to the electron repo! https://github.com/getsentry/sentry-electron
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.
@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.
@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
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
});
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);
Use "Classic" IPC for Sentry communications
It works fine!
I truly appreciate your timely help.