useTraceTree.tsx 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. import {useEffect, useState} from 'react';
  2. import type {TraceSplitResults} from 'sentry/utils/performance/quickTrace/types';
  3. import type {QueryStatus, UseApiQueryResult} from 'sentry/utils/queryClient';
  4. import useApi from 'sentry/utils/useApi';
  5. import useOrganization from 'sentry/utils/useOrganization';
  6. import useProjects from 'sentry/utils/useProjects';
  7. import type {ReplayRecord} from 'sentry/views/replays/types';
  8. import {TraceTree} from '../traceModels/traceTree';
  9. import type {TraceMetaQueryResults} from './useTraceMeta';
  10. type UseTraceTreeParams = {
  11. meta: TraceMetaQueryResults;
  12. replay: ReplayRecord | null;
  13. trace: UseApiQueryResult<TraceSplitResults<TraceTree.Transaction> | undefined, any>;
  14. traceSlug?: string;
  15. };
  16. function getTraceViewQueryStatus(
  17. traceQueryStatus: QueryStatus,
  18. traceMetaQueryStatus: QueryStatus
  19. ): QueryStatus {
  20. if (traceQueryStatus === 'error' || traceMetaQueryStatus === 'error') {
  21. return 'error';
  22. }
  23. if (traceQueryStatus === 'pending' || traceMetaQueryStatus === 'pending') {
  24. return 'pending';
  25. }
  26. return 'success';
  27. }
  28. export function useTraceTree({
  29. trace,
  30. meta,
  31. replay,
  32. traceSlug,
  33. }: UseTraceTreeParams): TraceTree {
  34. const api = useApi();
  35. const {projects} = useProjects();
  36. const organization = useOrganization();
  37. const [tree, setTree] = useState<TraceTree>(TraceTree.Empty());
  38. useEffect(() => {
  39. const status = getTraceViewQueryStatus(trace.status, meta.status);
  40. if (status === 'error') {
  41. setTree(t =>
  42. t.type === 'error'
  43. ? t
  44. : TraceTree.Error({
  45. project_slug: projects?.[0]?.slug ?? '',
  46. event_id: traceSlug,
  47. })
  48. );
  49. return;
  50. }
  51. if (
  52. trace?.data?.transactions.length === 0 &&
  53. trace?.data?.orphan_errors.length === 0
  54. ) {
  55. setTree(t => (t.type === 'empty' ? t : TraceTree.Empty()));
  56. return;
  57. }
  58. if (status === 'pending') {
  59. setTree(t =>
  60. t.type === 'loading'
  61. ? t
  62. : TraceTree.Loading({
  63. project_slug: projects?.[0]?.slug ?? '',
  64. event_id: traceSlug,
  65. })
  66. );
  67. return;
  68. }
  69. if (trace.data && meta.data) {
  70. const newTree = TraceTree.FromTrace(trace.data, {
  71. meta: meta.data,
  72. replay: replay,
  73. });
  74. setTree(newTree);
  75. newTree.build();
  76. return;
  77. }
  78. }, [
  79. api,
  80. organization,
  81. projects,
  82. replay,
  83. meta.status,
  84. trace.status,
  85. trace.data,
  86. meta.data,
  87. traceSlug,
  88. ]);
  89. return tree;
  90. }