events.tsx 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. import {
  2. BaseGroup,
  3. EventMetadata,
  4. EventOrGroupType,
  5. GroupTombstone,
  6. TreeLabelPart,
  7. } from 'app/types';
  8. import {Event} from 'app/types/event';
  9. import {isNativePlatform} from 'app/utils/platform';
  10. function isTombstone(maybe: BaseGroup | Event | GroupTombstone): maybe is GroupTombstone {
  11. return !maybe.hasOwnProperty('type');
  12. }
  13. /**
  14. * Extract the display message from an event.
  15. */
  16. export function getMessage(
  17. event: Event | BaseGroup | GroupTombstone
  18. ): string | undefined {
  19. if (isTombstone(event)) {
  20. return event.culprit || '';
  21. }
  22. const {metadata, type, culprit} = event;
  23. switch (type) {
  24. case EventOrGroupType.ERROR:
  25. return metadata.value;
  26. case EventOrGroupType.CSP:
  27. return metadata.message;
  28. case EventOrGroupType.EXPECTCT:
  29. case EventOrGroupType.EXPECTSTAPLE:
  30. case EventOrGroupType.HPKP:
  31. return '';
  32. default:
  33. return culprit || '';
  34. }
  35. }
  36. /**
  37. * Get the location from an event.
  38. */
  39. export function getLocation(event: Event | BaseGroup | GroupTombstone) {
  40. if (isTombstone(event)) {
  41. return undefined;
  42. }
  43. if (event.type === EventOrGroupType.ERROR && isNativePlatform(event.platform)) {
  44. return event.metadata.filename || undefined;
  45. }
  46. return undefined;
  47. }
  48. export function formatTreeLabelPart(part: TreeLabelPart): string {
  49. if (typeof part === 'string') {
  50. return part;
  51. } else {
  52. return part?.function || part?.package || part?.type || '<unknown>';
  53. }
  54. }
  55. function computeTitleWithTreeLabel(metadata: EventMetadata) {
  56. const {type, current_tree_label, finest_tree_label} = metadata;
  57. const treeLabel = current_tree_label || finest_tree_label;
  58. const formattedTreeLabel = treeLabel
  59. ? treeLabel.map(formatTreeLabelPart).join(' | ')
  60. : undefined;
  61. if (!type) {
  62. return {
  63. title: formattedTreeLabel || metadata.function || '<unknown>',
  64. treeLabel,
  65. };
  66. }
  67. if (!formattedTreeLabel) {
  68. return {title: type, treeLabel: undefined};
  69. }
  70. return {
  71. title: `${type} | ${formattedTreeLabel}`,
  72. treeLabel: [{type}, ...(treeLabel ?? [])],
  73. };
  74. }
  75. export function getTitle(event: Event | BaseGroup, features: string[] = []) {
  76. const {metadata, type, culprit} = event;
  77. const customTitle =
  78. features.includes('custom-event-title') && metadata?.title
  79. ? metadata.title
  80. : undefined;
  81. switch (type) {
  82. case EventOrGroupType.ERROR: {
  83. if (customTitle) {
  84. return {
  85. title: customTitle,
  86. subtitle: culprit,
  87. treeLabel: undefined,
  88. };
  89. }
  90. return {
  91. subtitle: culprit,
  92. ...computeTitleWithTreeLabel(metadata),
  93. };
  94. }
  95. case EventOrGroupType.CSP:
  96. return {
  97. title: customTitle ?? metadata.directive ?? '',
  98. subtitle: metadata.uri ?? '',
  99. treeLabel: undefined,
  100. };
  101. case EventOrGroupType.EXPECTCT:
  102. case EventOrGroupType.EXPECTSTAPLE:
  103. case EventOrGroupType.HPKP:
  104. // Due to a regression some reports did not have message persisted
  105. // (https://github.com/getsentry/sentry/pull/19794) so we need to fall
  106. // back to the computed title for these.
  107. return {
  108. title: customTitle ?? (metadata.message || event.title),
  109. subtitle: metadata.origin ?? '',
  110. treeLabel: undefined,
  111. };
  112. case EventOrGroupType.DEFAULT:
  113. return {
  114. title: customTitle ?? metadata.title ?? '',
  115. subtitle: '',
  116. treeLabel: undefined,
  117. };
  118. default:
  119. return {
  120. title: customTitle ?? event.title,
  121. subtitle: '',
  122. treeLabel: undefined,
  123. };
  124. }
  125. }
  126. /**
  127. * Returns a short eventId with only 8 characters
  128. */
  129. export function getShortEventId(eventId: string) {
  130. return eventId.substring(0, 8);
  131. }