Sentry: use DSN from SoapboxConfig

This commit is contained in:
Alex Gleason 2023-10-05 16:33:59 -05:00
parent f02255ff6a
commit 73f407455e
No known key found for this signature in database
GPG key ID: 7211D1F99744FBB7
7 changed files with 80 additions and 52 deletions

View file

@ -28,8 +28,9 @@ import {
useAppSelector,
useAppDispatch,
useOwnAccount,
useSoapboxConfig,
useSentry,
useSettings,
useSoapboxConfig,
useTheme,
useLocale,
} from 'soapbox/hooks';
@ -224,6 +225,8 @@ const SoapboxHead: React.FC<ISoapboxHead> = ({ children }) => {
'demetricator': settings.get('demetricator'),
});
useSentry(soapboxConfig.sentryDsn);
return (
<>
<Helmet>

View file

@ -19,7 +19,8 @@ export { useOwnAccount } from './useOwnAccount';
export { usePrevious } from './usePrevious';
export { useRefEventHandler } from './useRefEventHandler';
export { useRegistrationStatus } from './useRegistrationStatus';
export { useSentry } from './useSentry';
export { useSettings } from './useSettings';
export { useSoapboxConfig } from './useSoapboxConfig';
export { useSystemTheme } from './useSystemTheme';
export { useTheme } from './useTheme';
export { useTheme } from './useTheme';

50
src/hooks/useSentry.ts Normal file
View file

@ -0,0 +1,50 @@
import { useEffect } from 'react';
/** Hook to start Sentry. Should only be called once. */
function useSentry(dsn: string | undefined) {
useEffect(() => {
if (dsn) {
startSentry(dsn).catch(console.error);
}
}, [dsn]);
}
/** Start Sentry. */
async function startSentry(dsn: string): Promise<void> {
const [Sentry, { Integrations: Integrations }] = await Promise.all([
import('@sentry/react'),
import('@sentry/tracing'),
]);
Sentry.init({
dsn,
debug: false,
integrations: [new Integrations.BrowserTracing()],
// Filter events.
// https://docs.sentry.io/platforms/javascript/configuration/filtering/
ignoreErrors: [
// Network errors.
'AxiosError',
// sw.js couldn't be downloaded.
'Failed to update a ServiceWorker for scope',
// Useful for try/catch, useless as a Sentry error.
'AbortError',
// localForage error in FireFox private browsing mode (which doesn't support IndexedDB).
// We only use IndexedDB as a cache, so we can safely ignore the error.
'No available storage method found',
],
denyUrls: [
// Browser extensions.
/extensions\//i,
/^chrome:\/\//i,
/^moz-extension:\/\//i,
],
// We recommend adjusting this value in production, or using tracesSampler
// for finer control
tracesSampleRate: 1.0,
});
}
export { useSentry };

View file

@ -23,13 +23,9 @@ import './styles/tailwind.css';
import './precheck';
import { default as Soapbox } from './containers/soapbox';
import * as monitoring from './monitoring';
import ready from './ready';
import { registerSW } from './utils/sw';
// Sentry
monitoring.start();
if (BuildConfig.NODE_ENV === 'production') {
printConsoleWarning();
registerSW('/sw.js');

View file

@ -1,49 +1,13 @@
import * as BuildConfig from 'soapbox/build-config';
import type { CaptureContext } from '@sentry/types';
export const start = (): void => {
Promise.all([
import('@sentry/react'),
import('@sentry/tracing'),
]).then(([Sentry, { Integrations: Integrations }]) => {
Sentry.init({
dsn: BuildConfig.SENTRY_DSN,
environment: BuildConfig.NODE_ENV,
debug: false,
integrations: [new Integrations.BrowserTracing()],
/** Capture the exception and report it to Sentry. */
async function captureException (exception: any, captureContext?: CaptureContext | undefined): Promise<void> {
try {
const Sentry = await import('@sentry/react');
Sentry.captureException(exception, captureContext);
} catch (e) {
console.error(e);
}
}
// Filter events.
// https://docs.sentry.io/platforms/javascript/configuration/filtering/
ignoreErrors: [
// Network errors.
'AxiosError',
// sw.js couldn't be downloaded.
'Failed to update a ServiceWorker for scope',
// Useful for try/catch, useless as a Sentry error.
'AbortError',
// localForage error in FireFox private browsing mode (which doesn't support IndexedDB).
// We only use IndexedDB as a cache, so we can safely ignore the error.
'No available storage method found',
],
denyUrls: [
// Browser extensions.
/extensions\//i,
/^chrome:\/\//i,
/^moz-extension:\/\//i,
],
// We recommend adjusting this value in production, or using tracesSampler
// for finer control
tracesSampleRate: 1.0,
});
}).catch(console.error);
};
export const captureException = (exception: any, captureContext?: CaptureContext | undefined): void => {
import('@sentry/react')
.then(Sentry => {
Sentry.captureException(exception, captureContext);
})
.catch(console.error);
};
export { captureException };

View file

@ -116,6 +116,7 @@ export const SoapboxConfigRecord = ImmutableRecord({
* On some platforms this can be too blurry without additional configuration.
*/
mediaPreview: false,
sentryDsn: undefined as string | undefined,
}, 'SoapboxConfig');
type SoapboxConfigMap = ImmutableMap<string, any>;

13
src/sentry.ts Normal file
View file

@ -0,0 +1,13 @@
import type { CaptureContext } from '@sentry/types';
/** Capture the exception in Sentry. */
async function captureException (exception: any, captureContext?: CaptureContext | undefined): Promise<void> {
try {
const Sentry = await import('@sentry/react');
Sentry.captureException(exception, captureContext);
} catch (e) {
console.error(e);
}
}
export { startSentry, captureException };