fix: prevent sentry from loading when telemetry is disabled (#10543)

Co-authored-by: forehalo <forehalo@gmail.com>
This commit is contained in:
hackerESQ
2025-03-05 06:09:38 -06:00
committed by GitHub
parent b247b8e26c
commit fed0e0add3
16 changed files with 122 additions and 200 deletions

View File

@@ -1,58 +1,24 @@
import './setup'; import './setup';
import { import { Telemetry } from '@affine/core/components/telemetry';
init, import { StrictMode } from 'react';
reactRouterV6BrowserTracingIntegration,
setTags,
} from '@sentry/react';
import { StrictMode, useEffect } from 'react';
import { createRoot } from 'react-dom/client'; import { createRoot } from 'react-dom/client';
import {
createRoutesFromChildren,
matchRoutes,
useLocation,
useNavigationType,
} from 'react-router-dom';
import { App } from './app'; import { App } from './app';
function main() {
if (BUILD_CONFIG.debug || window.SENTRY_RELEASE) {
// https://docs.sentry.io/platforms/javascript/guides/react/#configure
init({
dsn: process.env.SENTRY_DSN,
environment: process.env.BUILD_TYPE ?? 'development',
integrations: [
reactRouterV6BrowserTracingIntegration({
useEffect,
useLocation,
useNavigationType,
createRoutesFromChildren,
matchRoutes,
}),
],
});
setTags({
distribution: BUILD_CONFIG.distribution,
appVersion: BUILD_CONFIG.appVersion,
editorVersion: BUILD_CONFIG.editorVersion,
});
}
mountApp();
}
function mountApp() { function mountApp() {
// oxlint-disable-next-line @typescript-eslint/no-non-null-assertion // oxlint-disable-next-line no-non-null-assertion
const root = document.getElementById('app')!; const root = document.getElementById('app')!;
createRoot(root).render( createRoot(root).render(
<StrictMode> <StrictMode>
<Telemetry />
<App /> <App />
</StrictMode> </StrictMode>
); );
} }
try { try {
main(); mountApp();
} catch (err) { } catch (err) {
console.error('Failed to bootstrap app', err); console.error('Failed to bootstrap app', err);
} }

View File

@@ -1,46 +1,13 @@
import './setup'; import './setup';
import { appConfigProxy } from '@affine/core/components/hooks/use-app-config-storage'; import { appConfigProxy } from '@affine/core/components/hooks/use-app-config-storage';
import { import { Telemetry } from '@affine/core/components/telemetry';
init, import { StrictMode } from 'react';
reactRouterV6BrowserTracingIntegration,
setTags,
} from '@sentry/react';
import { StrictMode, useEffect } from 'react';
import { createRoot } from 'react-dom/client'; import { createRoot } from 'react-dom/client';
import {
createRoutesFromChildren,
matchRoutes,
useLocation,
useNavigationType,
} from 'react-router-dom';
import { App } from './app'; import { App } from './app';
function main() { function main() {
// skip bootstrap setup for desktop onboarding
if (BUILD_CONFIG.debug || window.SENTRY_RELEASE) {
// https://docs.sentry.io/platforms/javascript/guides/react/#configure
init({
dsn: process.env.SENTRY_DSN,
environment: process.env.BUILD_TYPE ?? 'development',
integrations: [
reactRouterV6BrowserTracingIntegration({
useEffect,
useLocation,
useNavigationType,
createRoutesFromChildren,
matchRoutes,
}),
],
});
setTags({
distribution: BUILD_CONFIG.distribution,
appVersion: BUILD_CONFIG.appVersion,
editorVersion: BUILD_CONFIG.editorVersion,
});
}
// load persistent config for electron // load persistent config for electron
// TODO(@Peng): should be sync, but it's not necessary for now // TODO(@Peng): should be sync, but it's not necessary for now
appConfigProxy appConfigProxy
@@ -55,6 +22,7 @@ function mountApp() {
const root = document.getElementById('app')!; const root = document.getElementById('app')!;
createRoot(root).render( createRoot(root).render(
<StrictMode> <StrictMode>
<Telemetry />
<App /> <App />
</StrictMode> </StrictMode>
); );

View File

@@ -2,20 +2,10 @@ import './setup';
import '@affine/component/theme'; import '@affine/component/theme';
import '@affine/core/mobile/styles/mobile.css'; import '@affine/core/mobile/styles/mobile.css';
import { Telemetry } from '@affine/core/components/telemetry';
import { bindNativeDBApis } from '@affine/nbstore/sqlite'; import { bindNativeDBApis } from '@affine/nbstore/sqlite';
import { import { StrictMode } from 'react';
init,
reactRouterV6BrowserTracingIntegration,
setTags,
} from '@sentry/react';
import { StrictMode, useEffect } from 'react';
import { createRoot } from 'react-dom/client'; import { createRoot } from 'react-dom/client';
import {
createRoutesFromChildren,
matchRoutes,
useLocation,
useNavigationType,
} from 'react-router-dom';
import { App } from './app'; import { App } from './app';
import { NbStoreNativeDBApis } from './plugins/nbstore'; import { NbStoreNativeDBApis } from './plugins/nbstore';
@@ -25,43 +15,19 @@ bindNativeDBApis(NbStoreNativeDBApis);
// TODO(@L-Sun) Uncomment this when the `show` method implement by `@capacitor/keyboard` in ios // TODO(@L-Sun) Uncomment this when the `show` method implement by `@capacitor/keyboard` in ios
// import './virtual-keyboard'; // import './virtual-keyboard';
function main() {
if (BUILD_CONFIG.debug || window.SENTRY_RELEASE) {
// https://docs.sentry.io/platforms/javascript/guides/react/#configure
init({
dsn: process.env.SENTRY_DSN,
environment: process.env.BUILD_TYPE ?? 'development',
integrations: [
reactRouterV6BrowserTracingIntegration({
useEffect,
useLocation,
useNavigationType,
createRoutesFromChildren,
matchRoutes,
}),
],
});
setTags({
distribution: BUILD_CONFIG.distribution,
appVersion: BUILD_CONFIG.appVersion,
editorVersion: BUILD_CONFIG.editorVersion,
});
}
mountApp();
}
function mountApp() { function mountApp() {
// oxlint-disable-next-line @typescript-eslint/no-non-null-assertion // oxlint-disable-next-line @typescript-eslint/no-non-null-assertion
const root = document.getElementById('app')!; const root = document.getElementById('app')!;
createRoot(root).render( createRoot(root).render(
<StrictMode> <StrictMode>
<Telemetry />
<App /> <App />
</StrictMode> </StrictMode>
); );
} }
try { try {
main(); mountApp();
} catch (err) { } catch (err) {
console.error('Failed to bootstrap app', err); console.error('Failed to bootstrap app', err);
} }

View File

@@ -1,58 +1,24 @@
import './setup'; import './setup';
import { import { Telemetry } from '@affine/core/components/telemetry';
init, import { StrictMode } from 'react';
reactRouterV6BrowserTracingIntegration,
setTags,
} from '@sentry/react';
import { StrictMode, useEffect } from 'react';
import { createRoot } from 'react-dom/client'; import { createRoot } from 'react-dom/client';
import {
createRoutesFromChildren,
matchRoutes,
useLocation,
useNavigationType,
} from 'react-router-dom';
import { App } from './app'; import { App } from './app';
function main() {
if (BUILD_CONFIG.debug || window.SENTRY_RELEASE) {
// https://docs.sentry.io/platforms/javascript/guides/react/#configure
init({
dsn: process.env.SENTRY_DSN,
environment: process.env.BUILD_TYPE ?? 'development',
integrations: [
reactRouterV6BrowserTracingIntegration({
useEffect,
useLocation,
useNavigationType,
createRoutesFromChildren,
matchRoutes,
}),
],
});
setTags({
distribution: BUILD_CONFIG.distribution,
appVersion: BUILD_CONFIG.appVersion,
editorVersion: BUILD_CONFIG.editorVersion,
});
}
mountApp();
}
function mountApp() { function mountApp() {
// oxlint-disable-next-line no-non-null-assertion // oxlint-disable-next-line no-non-null-assertion
const root = document.getElementById('app')!; const root = document.getElementById('app')!;
createRoot(root).render( createRoot(root).render(
<StrictMode> <StrictMode>
<Telemetry />
<App /> <App />
</StrictMode> </StrictMode>
); );
} }
try { try {
main(); mountApp();
} catch (err) { } catch (err) {
console.error('Failed to bootstrap app', err); console.error('Failed to bootstrap app', err);
} }

View File

@@ -13,6 +13,7 @@
"@affine/core": "workspace:*", "@affine/core": "workspace:*",
"@affine/i18n": "workspace:*", "@affine/i18n": "workspace:*",
"@affine/nbstore": "workspace:*", "@affine/nbstore": "workspace:*",
"@affine/track": "workspace:*",
"@emotion/react": "^11.14.0", "@emotion/react": "^11.14.0",
"@sentry/react": "^9.2.0", "@sentry/react": "^9.2.0",
"@toeverything/infra": "workspace:*", "@toeverything/infra": "workspace:*",

View File

@@ -1,60 +1,24 @@
import './setup'; import './setup';
import { import { Telemetry } from '@affine/core/components/telemetry';
init, import { StrictMode } from 'react';
reactRouterV6BrowserTracingIntegration,
setTags,
} from '@sentry/react';
import { StrictMode, useEffect } from 'react';
import { createRoot } from 'react-dom/client'; import { createRoot } from 'react-dom/client';
import {
createRoutesFromChildren,
matchRoutes,
useLocation,
useNavigationType,
} from 'react-router-dom';
import { App } from './app'; import { App } from './app';
function main() {
// skip bootstrap setup for desktop onboarding
if (BUILD_CONFIG.debug || window.SENTRY_RELEASE) {
// https://docs.sentry.io/platforms/javascript/guides/react/#configure
init({
dsn: process.env.SENTRY_DSN,
environment: process.env.BUILD_TYPE ?? 'development',
integrations: [
reactRouterV6BrowserTracingIntegration({
useEffect,
useLocation,
useNavigationType,
createRoutesFromChildren,
matchRoutes,
}),
],
});
setTags({
distribution: BUILD_CONFIG.distribution,
appVersion: BUILD_CONFIG.appVersion,
editorVersion: BUILD_CONFIG.editorVersion,
});
}
mountApp();
}
function mountApp() { function mountApp() {
// oxlint-disable-next-line @typescript-eslint/no-non-null-assertion // oxlint-disable-next-line @typescript-eslint/no-non-null-assertion
const root = document.getElementById('app')!; const root = document.getElementById('app')!;
createRoot(root).render( createRoot(root).render(
<StrictMode> <StrictMode>
<Telemetry />
<App /> <App />
</StrictMode> </StrictMode>
); );
} }
try { try {
main(); mountApp();
} catch (err) { } catch (err) {
console.error('Failed to bootstrap app', err); console.error('Failed to bootstrap app', err);
} }

View File

@@ -2,3 +2,4 @@
import './env'; import './env';
import './public-path'; import './public-path';
import './polyfill/browser'; import './polyfill/browser';
import './telemetry';

View File

@@ -2,3 +2,4 @@
import './env'; import './env';
import './public-path'; import './public-path';
import './polyfill/electron'; import './polyfill/electron';
import './telemetry';

View File

@@ -0,0 +1,4 @@
import { mixpanel, sentry } from '@affine/track';
mixpanel.init();
sentry.init();

View File

@@ -1,4 +1,4 @@
import { enableAutoTrack, mixpanel } from '@affine/track'; import { enableAutoTrack, mixpanel, sentry } from '@affine/track';
import { appSettingAtom } from '@toeverything/infra'; import { appSettingAtom } from '@toeverything/infra';
import { useAtomValue } from 'jotai/react'; import { useAtomValue } from 'jotai/react';
import { useLayoutEffect } from 'react'; import { useLayoutEffect } from 'react';
@@ -7,9 +7,12 @@ export function Telemetry() {
const settings = useAtomValue(appSettingAtom); const settings = useAtomValue(appSettingAtom);
useLayoutEffect(() => { useLayoutEffect(() => {
if (settings.enableTelemetry === false) { if (settings.enableTelemetry === false) {
sentry.disable();
mixpanel.opt_out_tracking(); mixpanel.opt_out_tracking();
return; return;
} else { } else {
sentry.enable();
mixpanel.opt_in_tracking();
return enableAutoTrack(document.body, mixpanel.track); return enableAutoTrack(document.body, mixpanel.track);
} }
}, [settings.enableTelemetry]); }, [settings.enableTelemetry]);

View File

@@ -8,7 +8,6 @@ import { useAppUpdater } from '@affine/core/components/hooks/use-app-updater';
import { UrlService } from '@affine/core/modules/url'; import { UrlService } from '@affine/core/modules/url';
import { appIconMap, appNames } from '@affine/core/utils/channel'; import { appIconMap, appNames } from '@affine/core/utils/channel';
import { useI18n } from '@affine/i18n'; import { useI18n } from '@affine/i18n';
import { mixpanel } from '@affine/track';
import { ArrowRightSmallIcon, OpenInNewIcon } from '@blocksuite/icons/rc'; import { ArrowRightSmallIcon, OpenInNewIcon } from '@blocksuite/icons/rc';
import { useServices } from '@toeverything/infra'; import { useServices } from '@toeverything/infra';
import { useCallback } from 'react'; import { useCallback } from 'react';
@@ -47,11 +46,6 @@ export const AboutAffine = () => {
const onSwitchTelemetry = useCallback( const onSwitchTelemetry = useCallback(
(checked: boolean) => { (checked: boolean) => {
if (!checked) {
mixpanel.opt_out_tracking();
} else {
mixpanel.opt_in_tracking();
}
updateSettings('enableTelemetry', checked); updateSettings('enableTelemetry', checked);
}, },
[updateSettings] [updateSettings]

View File

@@ -9,10 +9,13 @@
"sideEffects": "false", "sideEffects": "false",
"dependencies": { "dependencies": {
"@affine/debug": "workspace:*", "@affine/debug": "workspace:*",
"mixpanel-browser": "^2.56.0" "@sentry/react": "^9.2.0",
"mixpanel-browser": "^2.56.0",
"react-router-dom": "6.28.0"
}, },
"devDependencies": { "devDependencies": {
"@types/mixpanel-browser": "^2.50.2", "@types/mixpanel-browser": "^2.50.2",
"@types/react": "^19.0.1",
"vitest": "^3.0.0" "vitest": "^3.0.0"
} }
} }

View File

@@ -1,9 +1,10 @@
import { enableAutoTrack, makeTracker } from './auto'; import { enableAutoTrack, makeTracker } from './auto';
import { mixpanel } from './mixpanel'; import { mixpanel } from './mixpanel';
import { sentry } from './sentry';
export const track = makeTracker((event, props) => { export const track = makeTracker((event, props) => {
mixpanel.track(event, props); mixpanel.track(event, props);
}); });
export { enableAutoTrack, mixpanel }; export { enableAutoTrack, mixpanel, sentry };
export default track; export default track;

View File

@@ -94,7 +94,6 @@ function createMixpanel() {
} }
export const mixpanel = createMixpanel(); export const mixpanel = createMixpanel();
mixpanel.init();
function createProxyHandler() { function createProxyHandler() {
const handler = { const handler = {

View File

@@ -0,0 +1,50 @@
import * as Sentry from '@sentry/react';
import { useEffect } from 'react';
import {
createRoutesFromChildren,
matchRoutes,
useLocation,
useNavigationType,
} from 'react-router-dom';
function createSentry() {
let enabled = true;
const wrapped = {
init() {
// https://docs.sentry.io/platforms/javascript/guides/react/#configure
Sentry.init({
enabled: enabled,
dsn: process.env.SENTRY_DSN,
debug: BUILD_CONFIG.debug ?? false,
environment: process.env.BUILD_TYPE ?? 'development',
integrations: [
Sentry.reactRouterV6BrowserTracingIntegration({
useEffect,
useLocation,
useNavigationType,
createRoutesFromChildren,
matchRoutes,
}),
],
beforeSend(event) {
return enabled ? event : null;
},
});
Sentry.setTags({
distribution: BUILD_CONFIG.distribution,
appVersion: BUILD_CONFIG.appVersion,
editorVersion: BUILD_CONFIG.editorVersion,
});
},
enable() {
enabled = true;
},
disable() {
enabled = false;
},
};
return wrapped;
}
export const sentry = createSentry();

View File

@@ -935,8 +935,11 @@ __metadata:
resolution: "@affine/track@workspace:packages/frontend/track" resolution: "@affine/track@workspace:packages/frontend/track"
dependencies: dependencies:
"@affine/debug": "workspace:*" "@affine/debug": "workspace:*"
"@sentry/react": "npm:^9.2.0"
"@types/mixpanel-browser": "npm:^2.50.2" "@types/mixpanel-browser": "npm:^2.50.2"
"@types/react": "npm:^19.0.1"
mixpanel-browser: "npm:^2.56.0" mixpanel-browser: "npm:^2.56.0"
react-router-dom: "npm:6.28.0"
vitest: "npm:^3.0.0" vitest: "npm:^3.0.0"
languageName: unknown languageName: unknown
linkType: soft linkType: soft
@@ -949,6 +952,7 @@ __metadata:
"@affine/core": "workspace:*" "@affine/core": "workspace:*"
"@affine/i18n": "workspace:*" "@affine/i18n": "workspace:*"
"@affine/nbstore": "workspace:*" "@affine/nbstore": "workspace:*"
"@affine/track": "workspace:*"
"@emotion/react": "npm:^11.14.0" "@emotion/react": "npm:^11.14.0"
"@sentry/react": "npm:^9.2.0" "@sentry/react": "npm:^9.2.0"
"@toeverything/infra": "workspace:*" "@toeverything/infra": "workspace:*"
@@ -11224,6 +11228,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@remix-run/router@npm:1.21.0":
version: 1.21.0
resolution: "@remix-run/router@npm:1.21.0"
checksum: 10/cf0fb69d19c1b79095ff67c59cea89086f3982a9a54c8a993818a60fc76e0ebab5a8db647c1a96a662729fad8e806ddd0a96622adf473f5a9f0b99998b2dbad4
languageName: node
linkType: hard
"@remix-run/router@npm:1.23.0": "@remix-run/router@npm:1.23.0":
version: 1.23.0 version: 1.23.0
resolution: "@remix-run/router@npm:1.23.0" resolution: "@remix-run/router@npm:1.23.0"
@@ -28807,6 +28818,19 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"react-router-dom@npm:6.28.0":
version: 6.28.0
resolution: "react-router-dom@npm:6.28.0"
dependencies:
"@remix-run/router": "npm:1.21.0"
react-router: "npm:6.28.0"
peerDependencies:
react: ">=16.8"
react-dom: ">=16.8"
checksum: 10/e637825132ea96c3514ef7b8322f9bf0b752a942d6b4ffc4c20e389b5911726adf3dba8208ed4b97bf5b9c3bd465d9d1a1db1a58a610a8d528f18d890e0b143f
languageName: node
linkType: hard
"react-router-dom@npm:^6.28.0": "react-router-dom@npm:^6.28.0":
version: 6.30.0 version: 6.30.0
resolution: "react-router-dom@npm:6.30.0" resolution: "react-router-dom@npm:6.30.0"
@@ -28820,6 +28844,17 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"react-router@npm:6.28.0":
version: 6.28.0
resolution: "react-router@npm:6.28.0"
dependencies:
"@remix-run/router": "npm:1.21.0"
peerDependencies:
react: ">=16.8"
checksum: 10/f021a644513144884a567d9c2dcc432e8e3233f931378c219c5a3b5b842340f0faca86225a708bafca1e9010965afe1a7dada28aef5b7b6138c885c0552d9a7d
languageName: node
linkType: hard
"react-router@npm:6.30.0": "react-router@npm:6.30.0":
version: 6.30.0 version: 6.30.0
resolution: "react-router@npm:6.30.0" resolution: "react-router@npm:6.30.0"