Files
UT-Registration-Plus/src/views/contexts/SentryContext.tsx
2024-10-23 14:15:47 -05:00

99 lines
3.1 KiB
TypeScript

import {
BrowserClient,
defaultStackParser,
ErrorBoundary,
getCurrentScope,
getDefaultIntegrations,
init,
makeFetchTransport,
Scope,
} from '@sentry/react';
import type { Client, ClientOptions } from '@sentry/types';
import React, { createContext, useContext, useMemo } from 'react';
/**
* Context for the sentry provider.
*/
export const SentryContext = createContext<[scope: Scope, client: Client]>(undefined!);
/**
* @returns The dialog context for showing dialogs.
*/
export const useSentryScope = () => useContext(SentryContext);
/**
* SentryProvider component initializes and provides Sentry error tracking context to its children.
* It ensures that Sentry is not initialized more than once and configures the Sentry client and scope.
*
* @param props - The properties object.
* @param props.children - The child components that will have access to the Sentry context.
* @param props.transactionName - Optional name for the Sentry transaction.
* @param props.fullInit - Flag to determine if full initialization of Sentry should be performed.
*
* @returns The Sentry context provider wrapping the children components.
*/
export default function SentryProvider({
children,
transactionName,
fullInit,
}: {
children: React.ReactNode;
transactionName?: string;
fullInit?: boolean;
}): JSX.Element {
// prevent accidentally initializing sentry twice
const parent = useSentryScope();
const providerValue = useMemo((): [scope: Scope, client: Client] => {
if (parent) {
const [parentScope, parentClient] = parent;
const scope = parentScope.clone();
if (transactionName) scope.setTransactionName(transactionName);
return [scope, parentClient];
}
// filter integrations that use the global variable
const integrations = getDefaultIntegrations({}).filter(
defaultIntegration =>
!['BrowserApiErrors', 'Breadcrumbs', 'GlobalHandlers'].includes(defaultIntegration.name)
);
const options: ClientOptions = {
dsn: 'https://ed1a50d8626ff6be35b98d7b1ec86d9d@o4508033820852224.ingest.us.sentry.io/4508033822490624',
integrations,
transport: makeFetchTransport,
stackParser: defaultStackParser,
debug: import.meta.env.DEV,
release: import.meta.env.VITE_PACKAGE_VERSION,
environment: import.meta.env.VITE_SENTRY_ENVIRONMENT,
};
let client: Client;
let scope: Scope;
if (fullInit) {
client = init(options)!;
scope = getCurrentScope();
} else {
client = new BrowserClient(options);
scope = new Scope();
scope.setClient(client);
client.init();
}
return [scope, client];
// This is on purpose to only run once
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return (
<ErrorBoundary>
<SentryContext.Provider value={providerValue}>{children}</SentryContext.Provider>
</ErrorBoundary>
);
}