quickTraceQuery.tsx 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. import {Fragment} from 'react';
  2. import {Event} from 'sentry/types/event';
  3. import {DiscoverQueryProps} from 'sentry/utils/discover/genericDiscoverQuery';
  4. import {TraceFullQuery} from 'sentry/utils/performance/quickTrace/traceFullQuery';
  5. import TraceLiteQuery from 'sentry/utils/performance/quickTrace/traceLiteQuery';
  6. import {
  7. QuickTraceQueryChildrenProps,
  8. TraceFull,
  9. TraceSplitResults,
  10. } from 'sentry/utils/performance/quickTrace/types';
  11. import {
  12. flattenRelevantPaths,
  13. getTraceTimeRangeFromEvent,
  14. isCurrentEvent,
  15. isTraceSplitResult,
  16. } from 'sentry/utils/performance/quickTrace/utils';
  17. import useOrganization from 'sentry/utils/useOrganization';
  18. type QueryProps = Omit<DiscoverQueryProps, 'api' | 'eventView'> & {
  19. children: (props: QuickTraceQueryChildrenProps) => React.ReactNode;
  20. event: Event | undefined;
  21. };
  22. export default function QuickTraceQuery({children, event, ...props}: QueryProps) {
  23. const organization = useOrganization();
  24. const renderEmpty = () => (
  25. <Fragment>
  26. {children({
  27. isLoading: false,
  28. error: null,
  29. trace: [],
  30. type: 'empty',
  31. currentEvent: null,
  32. })}
  33. </Fragment>
  34. );
  35. if (!event) {
  36. return renderEmpty();
  37. }
  38. const traceId = event.contexts?.trace?.trace_id;
  39. if (!traceId) {
  40. return renderEmpty();
  41. }
  42. const {start, end} = getTraceTimeRangeFromEvent(event);
  43. return (
  44. <TraceLiteQuery
  45. eventId={event.id}
  46. traceId={traceId}
  47. start={start}
  48. end={end}
  49. {...props}
  50. >
  51. {traceLiteResults => (
  52. <TraceFullQuery
  53. eventId={event.id}
  54. traceId={traceId}
  55. start={start}
  56. end={end}
  57. {...props}
  58. >
  59. {traceFullResults => {
  60. if (
  61. !traceFullResults.isLoading &&
  62. traceFullResults.error === null &&
  63. traceFullResults.traces !== null
  64. ) {
  65. if (
  66. organization.features.includes(
  67. 'performance-tracing-without-performance'
  68. ) &&
  69. isTraceSplitResult<TraceSplitResults<TraceFull>, TraceFull[]>(
  70. traceFullResults.traces
  71. )
  72. ) {
  73. traceFullResults.traces = traceFullResults.traces.transactions;
  74. }
  75. if (
  76. !isTraceSplitResult<TraceSplitResults<TraceFull>, TraceFull[]>(
  77. traceFullResults.traces
  78. )
  79. ) {
  80. for (const subtrace of traceFullResults.traces) {
  81. try {
  82. const trace = flattenRelevantPaths(event, subtrace);
  83. return children({
  84. ...traceFullResults,
  85. trace,
  86. currentEvent: trace.find(e => isCurrentEvent(e, event)) ?? null,
  87. });
  88. } catch {
  89. // let this fall through and check the next subtrace
  90. // or use the trace lite results
  91. }
  92. }
  93. }
  94. }
  95. if (
  96. !traceLiteResults.isLoading &&
  97. traceLiteResults.error === null &&
  98. traceLiteResults.trace !== null
  99. ) {
  100. const {trace} = traceLiteResults;
  101. return children({
  102. ...traceLiteResults,
  103. currentEvent: trace.find(e => isCurrentEvent(e, event)) ?? null,
  104. });
  105. }
  106. return children({
  107. // only use the light results loading state if it didn't error
  108. // if it did, we should rely on the full results
  109. isLoading: traceLiteResults.error
  110. ? traceFullResults.isLoading
  111. : traceLiteResults.isLoading || traceFullResults.isLoading,
  112. // swallow any errors from the light results because we
  113. // should rely on the full results in this situations
  114. error: traceFullResults.error,
  115. trace: [],
  116. // if we reach this point but there were some traces in the full results,
  117. // that means there were other transactions in the trace, but the current
  118. // event could not be found
  119. type:
  120. traceFullResults.traces &&
  121. !isTraceSplitResult<TraceSplitResults<TraceFull>, TraceFull[]>(
  122. traceFullResults.traces
  123. ) &&
  124. traceFullResults.traces?.length
  125. ? 'missing'
  126. : 'empty',
  127. currentEvent: null,
  128. });
  129. }}
  130. </TraceFullQuery>
  131. )}
  132. </TraceLiteQuery>
  133. );
  134. }