2023-10-21 10:43:32 -07:00
|
|
|
import { NODE_ENV } from 'soapbox/build-config';
|
2023-10-12 19:51:06 -07:00
|
|
|
import sourceCode from 'soapbox/utils/code';
|
|
|
|
|
2023-10-12 18:07:48 -07:00
|
|
|
import type { Account } from './schemas';
|
2023-10-21 15:39:39 -07:00
|
|
|
import type { CaptureContext, UserFeedback } from '@sentry/types';
|
|
|
|
import type { SetOptional } from 'type-fest';
|
2023-10-12 18:07:48 -07:00
|
|
|
|
2023-10-05 14:33:59 -07:00
|
|
|
/** Start Sentry. */
|
|
|
|
async function startSentry(dsn: string): Promise<void> {
|
2023-10-21 15:51:23 -07:00
|
|
|
const Sentry = await import('@sentry/react');
|
2023-10-05 14:33:59 -07:00
|
|
|
|
|
|
|
Sentry.init({
|
|
|
|
dsn,
|
|
|
|
debug: false,
|
2023-10-21 10:43:32 -07:00
|
|
|
enabled: NODE_ENV === 'production',
|
2023-10-21 15:51:23 -07:00
|
|
|
integrations: [new Sentry.BrowserTracing()],
|
2023-10-05 14:33:59 -07:00
|
|
|
|
|
|
|
// 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',
|
2023-10-15 15:12:48 -07:00
|
|
|
// Virtuoso throws these errors, but it is a false-positive.
|
|
|
|
// https://github.com/petyosi/react-virtuoso/issues/254
|
|
|
|
'ResizeObserver loop completed with undelivered notifications.',
|
|
|
|
'ResizeObserver loop limit exceeded',
|
2023-10-05 14:33:59 -07:00
|
|
|
],
|
|
|
|
denyUrls: [
|
|
|
|
// Browser extensions.
|
|
|
|
/extensions\//i,
|
|
|
|
/^chrome:\/\//i,
|
|
|
|
/^moz-extension:\/\//i,
|
|
|
|
],
|
|
|
|
|
|
|
|
tracesSampleRate: 1.0,
|
|
|
|
});
|
2023-10-12 19:51:06 -07:00
|
|
|
|
|
|
|
Sentry.setContext('soapbox', sourceCode);
|
2023-10-05 14:33:59 -07:00
|
|
|
}
|
|
|
|
|
2023-10-12 18:07:48 -07:00
|
|
|
/** Associate the account with Sentry events. */
|
2023-10-21 12:21:21 -07:00
|
|
|
async function setSentryAccount(account: Account): Promise<void> {
|
2023-10-12 18:07:48 -07:00
|
|
|
const Sentry = await import('@sentry/react');
|
|
|
|
|
|
|
|
Sentry.setUser({
|
|
|
|
id: account.id,
|
|
|
|
username: account.acct,
|
2023-10-12 19:51:06 -07:00
|
|
|
url: account.url,
|
2023-10-12 18:07:48 -07:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2023-10-12 19:56:14 -07:00
|
|
|
/** Remove the account from Sentry events. */
|
2023-10-21 12:21:21 -07:00
|
|
|
async function unsetSentryAccount(): Promise<void> {
|
2023-10-12 19:56:14 -07:00
|
|
|
const Sentry = await import('@sentry/react');
|
|
|
|
Sentry.setUser(null);
|
|
|
|
}
|
|
|
|
|
2023-10-21 12:18:56 -07:00
|
|
|
/** Capture the exception and report it to Sentry. */
|
2023-10-21 12:21:21 -07:00
|
|
|
async function captureSentryException (
|
|
|
|
exception: any,
|
|
|
|
captureContext?: CaptureContext | undefined,
|
|
|
|
): Promise<string> {
|
2023-10-21 12:18:56 -07:00
|
|
|
const Sentry = await import('@sentry/react');
|
2023-10-21 12:21:21 -07:00
|
|
|
return Sentry.captureException(exception, captureContext);
|
2023-10-21 12:18:56 -07:00
|
|
|
}
|
|
|
|
|
2023-10-21 15:39:39 -07:00
|
|
|
/** Capture user feedback and report it to Sentry. */
|
|
|
|
async function captureSentryFeedback(feedback: SetOptional<UserFeedback, 'name' | 'email'>): Promise<void> {
|
|
|
|
const Sentry = await import('@sentry/react');
|
|
|
|
Sentry.captureUserFeedback(feedback as UserFeedback);
|
|
|
|
}
|
|
|
|
|
|
|
|
export {
|
|
|
|
startSentry,
|
|
|
|
setSentryAccount,
|
|
|
|
unsetSentryAccount,
|
|
|
|
captureSentryException,
|
|
|
|
captureSentryFeedback,
|
|
|
|
};
|