useIssuesTraceTree.tsx 2.8 KB

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