bigbuffet-rw/packages/pl-fe/src/sentry.ts

80 lines
2.4 KiB
TypeScript
Raw Normal View History

import { NODE_ENV } from 'pl-fe/build-config';
import sourceCode from 'pl-fe/utils/code';
2023-10-12 19:51:06 -07:00
import type { CaptureContext, UserFeedback } from '@sentry/types';
import type { Account } from 'pl-api';
import type { SetOptional } from 'type-fest';
2023-10-12 18:07:48 -07:00
2023-10-05 14:33:59 -07:00
/** Start Sentry. */
const startSentry = async (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',
integrations: [Sentry.browserTracingIntegration()],
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',
],
denyUrls: [
// Browser extensions.
/extensions\//i,
/^chrome:\/\//i,
/^moz-extension:\/\//i,
],
tracesSampleRate: .1,
2023-10-05 14:33:59 -07:00
});
2023-10-12 19:51:06 -07:00
Sentry.setContext('pl-fe', sourceCode);
};
2023-10-05 14:33:59 -07:00
2023-10-12 18:07:48 -07:00
/** Associate the account with Sentry events. */
const setSentryAccount = async (account: Pick<Account, 'id' | 'acct' | 'url'>): 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 18:07:48 -07:00
/** Remove the account from Sentry events. */
const unsetSentryAccount = async (): Promise<void> => {
const Sentry = await import('@sentry/react');
Sentry.setUser(null);
};
/** Capture the exception and report it to Sentry. */
const captureSentryException = async (exception: any, captureContext?: CaptureContext | undefined): Promise<string> => {
const Sentry = await import('@sentry/react');
return Sentry.captureException(exception, captureContext);
};
/** Capture user feedback and report it to Sentry. */
const captureSentryFeedback = async (feedback: SetOptional<UserFeedback, 'name' | 'email'>): Promise<void> => {
const Sentry = await import('@sentry/react');
Sentry.captureUserFeedback(feedback as UserFeedback);
};
export {
startSentry,
setSentryAccount,
unsetSentryAccount,
captureSentryException,
captureSentryFeedback,
};