eventEntry.tsx 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. import ErrorBoundary from 'sentry/components/errorBoundary';
  2. import {EventDataSection} from 'sentry/components/events/eventDataSection';
  3. import {t} from 'sentry/locale';
  4. import type {Group, Organization, Project, SharedViewOrganization} from 'sentry/types';
  5. import type {Entry, Event, EventTransaction} from 'sentry/types/event';
  6. import {EntryType} from 'sentry/types/event';
  7. import {IssueCategory} from 'sentry/types/group';
  8. import {Breadcrumbs} from './interfaces/breadcrumbs';
  9. import {Csp} from './interfaces/csp';
  10. import {DebugMeta} from './interfaces/debugMeta';
  11. import {Exception} from './interfaces/exception';
  12. import {Generic} from './interfaces/generic';
  13. import {Message} from './interfaces/message';
  14. import {SpanEvidenceSection} from './interfaces/performance/spanEvidence';
  15. import {Request} from './interfaces/request';
  16. import {Spans} from './interfaces/spans';
  17. import {StackTrace} from './interfaces/stackTrace';
  18. import {Template} from './interfaces/template';
  19. import {Threads} from './interfaces/threads';
  20. type Props = {
  21. entry: Entry;
  22. event: Event;
  23. organization: SharedViewOrganization | Organization;
  24. projectSlug: Project['slug'];
  25. group?: Group;
  26. isShare?: boolean;
  27. };
  28. function EventEntryContent({
  29. entry,
  30. projectSlug,
  31. event,
  32. organization,
  33. group,
  34. isShare,
  35. }: Props) {
  36. const hasHierarchicalGrouping =
  37. !!organization.features?.includes('grouping-stacktrace-ui') &&
  38. !!(event.metadata.current_tree_label || event.metadata.finest_tree_label);
  39. const groupingCurrentLevel = group?.metadata?.current_level;
  40. switch (entry.type) {
  41. case EntryType.EXCEPTION:
  42. return (
  43. <Exception
  44. event={event}
  45. data={entry.data}
  46. projectSlug={projectSlug}
  47. groupingCurrentLevel={groupingCurrentLevel}
  48. hasHierarchicalGrouping={hasHierarchicalGrouping}
  49. />
  50. );
  51. case EntryType.MESSAGE:
  52. return <Message event={event} data={entry.data} />;
  53. case EntryType.REQUEST:
  54. return <Request event={event} data={entry.data} />;
  55. case EntryType.STACKTRACE:
  56. return (
  57. <StackTrace
  58. event={event}
  59. data={entry.data}
  60. projectSlug={projectSlug}
  61. groupingCurrentLevel={groupingCurrentLevel}
  62. hasHierarchicalGrouping={hasHierarchicalGrouping}
  63. />
  64. );
  65. case EntryType.TEMPLATE:
  66. return <Template event={event} data={entry.data} />;
  67. case EntryType.CSP:
  68. return <Csp event={event} data={entry.data} />;
  69. case EntryType.EXPECTCT:
  70. case EntryType.EXPECTSTAPLE:
  71. const {data, type} = entry;
  72. return <Generic type={type} data={data} />;
  73. case EntryType.HPKP:
  74. return (
  75. <Generic type={entry.type} data={entry.data} meta={event._meta?.hpkp ?? {}} />
  76. );
  77. case EntryType.BREADCRUMBS:
  78. return (
  79. <Breadcrumbs
  80. data={entry.data}
  81. organization={organization as Organization}
  82. event={event}
  83. />
  84. );
  85. case EntryType.THREADS:
  86. return (
  87. <Threads
  88. event={event}
  89. data={entry.data}
  90. projectSlug={projectSlug}
  91. groupingCurrentLevel={groupingCurrentLevel}
  92. hasHierarchicalGrouping={hasHierarchicalGrouping}
  93. organization={organization as Organization}
  94. />
  95. );
  96. case EntryType.DEBUGMETA:
  97. if (isShare) {
  98. return null;
  99. }
  100. return (
  101. <DebugMeta
  102. event={event}
  103. projectSlug={projectSlug}
  104. groupId={group?.id}
  105. organization={organization as Organization}
  106. data={entry.data}
  107. />
  108. );
  109. case EntryType.SPANS:
  110. // XXX: We currently do not show spans in the share view,
  111. if (isShare) {
  112. return null;
  113. }
  114. if (group?.issueCategory === IssueCategory.PERFORMANCE) {
  115. return (
  116. <SpanEvidenceSection
  117. event={event as EventTransaction}
  118. organization={organization as Organization}
  119. projectSlug={projectSlug}
  120. />
  121. );
  122. }
  123. return (
  124. <Spans
  125. event={event as EventTransaction}
  126. organization={organization as Organization}
  127. />
  128. );
  129. // this should not happen
  130. default:
  131. if (window.console) {
  132. // eslint-disable-next-line no-console
  133. console.error?.('Unregistered interface: ' + (entry as any).type);
  134. }
  135. return null;
  136. }
  137. }
  138. export function EventEntry(props: Props) {
  139. return (
  140. <ErrorBoundary
  141. customComponent={
  142. <EventDataSection type={props.entry.type} title={props.entry.type}>
  143. <p>{t('There was an error rendering this data.')}</p>
  144. </EventDataSection>
  145. }
  146. >
  147. <EventEntryContent {...props} />
  148. </ErrorBoundary>
  149. );
  150. }