profileGroupProvider.tsx 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. import {createContext, useContext, useMemo} from 'react';
  2. import * as Sentry from '@sentry/react';
  3. import {importProfile, ProfileGroup} from 'sentry/utils/profiling/profile/importProfile';
  4. type ProfileGroupContextValue = ProfileGroup;
  5. const ProfileGroupContext = createContext<ProfileGroupContextValue | null>(null);
  6. export function useProfileGroup() {
  7. const context = useContext(ProfileGroupContext);
  8. if (!context) {
  9. throw new Error('useProfileGroup was called outside of ProfileGroupProvider');
  10. }
  11. return context;
  12. }
  13. const LoadingGroup: ProfileGroup = {
  14. name: 'Loading',
  15. activeProfileIndex: 0,
  16. transactionID: null,
  17. metadata: {},
  18. measurements: {},
  19. traceID: '',
  20. profiles: [],
  21. };
  22. interface ProfileGroupProviderProps {
  23. children: React.ReactNode;
  24. input: Readonly<Profiling.ProfileInput> | null;
  25. traceID: string;
  26. type: 'flamegraph' | 'flamechart';
  27. }
  28. export function ProfileGroupProvider(props: ProfileGroupProviderProps) {
  29. const profileGroup = useMemo(() => {
  30. if (!props.input) {
  31. return LoadingGroup;
  32. }
  33. try {
  34. return importProfile(props.input, props.traceID, props.type);
  35. } catch (err) {
  36. Sentry.captureException(err);
  37. return LoadingGroup;
  38. }
  39. }, [props.input, props.traceID, props.type]);
  40. return (
  41. <ProfileGroupContext.Provider value={profileGroup}>
  42. {props.children}
  43. </ProfileGroupContext.Provider>
  44. );
  45. }