Merge branch 'sentry' into 'main'
Make Sentry integration actually useful See merge request soapbox-pub/soapbox!2777
This commit is contained in:
commit
232f9547b5
|
@ -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>
|
||||
|
|
|
@ -54,6 +54,8 @@ const messages = defineMessages({
|
|||
tileServerAttributionLabel: { id: 'soapbox_config.tile_server_attribution_label', defaultMessage: 'Map tiles attribution' },
|
||||
redirectRootNoLoginLabel: { id: 'soapbox_config.redirect_root_no_login_label', defaultMessage: 'Redirect homepage' },
|
||||
redirectRootNoLoginHint: { id: 'soapbox_config.redirect_root_no_login_hint', defaultMessage: 'Path to redirect the homepage when a user is not logged in.' },
|
||||
sentryDsnLabel: { id: 'soapbox_config.sentry_dsn_label', defaultMessage: 'Sentry DSN' },
|
||||
sentryDsnHint: { id: 'soapbox_config.sentry_dsn_hint', defaultMessage: 'DSN URL for error reporting. Works with Sentry and GlitchTip.' },
|
||||
});
|
||||
|
||||
type ValueGetter<T = Element> = (e: React.ChangeEvent<T>) => any;
|
||||
|
@ -285,6 +287,18 @@ const SoapboxConfig: React.FC = () => {
|
|||
onChange={handleChange(['redirectRootNoLogin'], (e) => e.target.value)}
|
||||
/>
|
||||
</ListItem>
|
||||
|
||||
<ListItem
|
||||
label={intl.formatMessage(messages.sentryDsnLabel)}
|
||||
hint={intl.formatMessage(messages.sentryDsnHint)}
|
||||
>
|
||||
<Input
|
||||
type='text'
|
||||
placeholder='https://01234abcdef@glitch.tip.tld/5678'
|
||||
value={String(data.get('sentryDsn', ''))}
|
||||
onChange={handleChange(['sentryDsn'], (e) => e.target.value)}
|
||||
/>
|
||||
</ListItem>
|
||||
</List>
|
||||
|
||||
<CardHeader>
|
||||
|
|
|
@ -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';
|
|
@ -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 };
|
|
@ -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');
|
||||
|
|
|
@ -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 };
|
||||
|
|
|
@ -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>;
|
||||
|
|
Loading…
Reference in New Issue