quickTraceQuery.tsx 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  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 {QuickTraceQueryChildrenProps} from 'sentry/utils/performance/quickTrace/types';
  7. import {
  8. flattenRelevantPaths,
  9. getTraceTimeRangeFromEvent,
  10. isCurrentEvent,
  11. } from 'sentry/utils/performance/quickTrace/utils';
  12. type QueryProps = Omit<DiscoverQueryProps, 'api' | 'eventView'> & {
  13. children: (props: QuickTraceQueryChildrenProps) => React.ReactNode;
  14. event: Event;
  15. };
  16. export default function QuickTraceQuery({children, event, ...props}: QueryProps) {
  17. const traceId = event.contexts?.trace?.trace_id;
  18. if (!traceId) {
  19. return (
  20. <Fragment>
  21. {children({
  22. isLoading: false,
  23. error: null,
  24. trace: [],
  25. type: 'empty',
  26. currentEvent: null,
  27. })}
  28. </Fragment>
  29. );
  30. }
  31. const {start, end} = getTraceTimeRangeFromEvent(event);
  32. return (
  33. <TraceLiteQuery
  34. eventId={event.id}
  35. traceId={traceId}
  36. start={start}
  37. end={end}
  38. {...props}
  39. >
  40. {traceLiteResults => (
  41. <TraceFullQuery
  42. eventId={event.id}
  43. traceId={traceId}
  44. start={start}
  45. end={end}
  46. {...props}
  47. >
  48. {traceFullResults => {
  49. if (
  50. !traceFullResults.isLoading &&
  51. traceFullResults.error === null &&
  52. traceFullResults.traces !== null
  53. ) {
  54. for (const subtrace of traceFullResults.traces) {
  55. try {
  56. const trace = flattenRelevantPaths(event, subtrace);
  57. return children({
  58. ...traceFullResults,
  59. trace,
  60. currentEvent: trace.find(e => isCurrentEvent(e, event)) ?? null,
  61. });
  62. } catch {
  63. // let this fall through and check the next subtrace
  64. // or use the trace lite results
  65. }
  66. }
  67. }
  68. if (
  69. !traceLiteResults.isLoading &&
  70. traceLiteResults.error === null &&
  71. traceLiteResults.trace !== null
  72. ) {
  73. const {trace} = traceLiteResults;
  74. return children({
  75. ...traceLiteResults,
  76. currentEvent: trace.find(e => isCurrentEvent(e, event)) ?? null,
  77. });
  78. }
  79. return children({
  80. // only use the light results loading state if it didn't error
  81. // if it did, we should rely on the full results
  82. isLoading: traceLiteResults.error
  83. ? traceFullResults.isLoading
  84. : traceLiteResults.isLoading || traceFullResults.isLoading,
  85. // swallow any errors from the light results because we
  86. // should rely on the full results in this situations
  87. error: traceFullResults.error,
  88. trace: [],
  89. // if we reach this point but there were some traces in the full results,
  90. // that means there were other transactions in the trace, but the current
  91. // event could not be found
  92. type: traceFullResults.traces?.length ? 'missing' : 'empty',
  93. currentEvent: null,
  94. });
  95. }}
  96. </TraceFullQuery>
  97. )}
  98. </TraceLiteQuery>
  99. );
  100. }