GH-2829 Add Sentry on frontend (#3111)

* GH-2829 pass sentry dsn key from backend in ClientConfig

* GH-2829 add Sentry library on frontend

* GH-2829 fetch dsnKey in GQL and add a state

* GH-2829 initialize Sentry on frontend

* GH-2829 fix linting issues

* Update yarn.lock

* GH-2829 update graphql schema for clientConfig

* GH-2829 remove Sentry comments

* GH-2829 rename sentry state

* GH-2829 rename dsnKey to dsn

* GH-2829 refactor to use componentEffect for sentry initialization

* GH-2829 fix linting issues

* GH-2829 update Graphql types

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
Deepak Kumar
2023-12-21 23:50:24 +01:00
committed by GitHub
co-authored by Charles Bochet
parent 756b30815e
commit 46ab88cb9c
13 changed files with 230 additions and 50 deletions
@@ -5,6 +5,7 @@ import { authProvidersState } from '@/client-config/states/authProvidersState';
import { billingState } from '@/client-config/states/billingState';
import { isDebugModeState } from '@/client-config/states/isDebugModeState';
import { isSignInPrefilledState } from '@/client-config/states/isSignInPrefilledState';
import { sentryConfigState } from '@/client-config/states/sentryConfigState';
import { supportChatState } from '@/client-config/states/supportChatState';
import { telemetryState } from '@/client-config/states/telemetryState';
import { useGetClientConfigQuery } from '~/generated/graphql';
@@ -21,6 +22,8 @@ export const ClientConfigProvider: React.FC<React.PropsWithChildren> = ({
const setTelemetry = useSetRecoilState(telemetryState);
const setSupportChat = useSetRecoilState(supportChatState);
const setSentryConfig = useSetRecoilState(sentryConfigState);
const { data, loading } = useGetClientConfigQuery();
useEffect(() => {
@@ -36,6 +39,10 @@ export const ClientConfigProvider: React.FC<React.PropsWithChildren> = ({
setBilling(data?.clientConfig.billing);
setTelemetry(data?.clientConfig.telemetry);
setSupportChat(data?.clientConfig.support);
setSentryConfig({
dsn: data?.clientConfig?.sentry?.dsn,
});
}
}, [
data,
@@ -45,6 +52,7 @@ export const ClientConfigProvider: React.FC<React.PropsWithChildren> = ({
setTelemetry,
setSupportChat,
setBilling,
setSentryConfig,
]);
return loading ? <></> : <>{children}</>;
@@ -21,6 +21,9 @@ export const GET_CLIENT_CONFIG = gql`
supportDriver
supportFrontChatId
}
sentry {
dsn
}
}
}
`;
@@ -0,0 +1,8 @@
import { atom } from 'recoil';
import { Sentry } from '~/generated/graphql';
export const sentryConfigState = atom<Sentry | null>({
key: 'sentryConfigState',
default: null,
});
@@ -0,0 +1,12 @@
import { SentryInitEffect } from '@/error-handler/components/SentryInitiEffect';
export const ExceptionHandlerProvider: React.FC<React.PropsWithChildren> = ({
children,
}) => {
return (
<>
<SentryInitEffect />
{children}
</>
);
};
@@ -0,0 +1,34 @@
import { useEffect, useState } from 'react';
import * as Sentry from '@sentry/react';
import { useRecoilValue } from 'recoil';
import { sentryConfigState } from '@/client-config/states/sentryConfigState';
import { REACT_APP_SERVER_BASE_URL } from '~/config';
export const SentryInitEffect = () => {
const sentryConfig = useRecoilValue(sentryConfigState);
const [isSentryInitialized, setIsSentryInitialized] = useState(false);
useEffect(() => {
if (sentryConfig?.dsn && !isSentryInitialized) {
Sentry.init({
dsn: sentryConfig?.dsn,
integrations: [
new Sentry.BrowserTracing({
tracePropagationTargets: [
'localhost:3001',
REACT_APP_SERVER_BASE_URL,
],
}),
new Sentry.Replay(),
],
tracesSampleRate: 1.0,
replaysSessionSampleRate: 0.1,
replaysOnErrorSampleRate: 1.0,
});
setIsSentryInitialized(true);
}
}, [sentryConfig, isSentryInitialized]);
return <></>;
};