utils.tsx 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. import {IconQuestion, IconWarning} from 'sentry/icons';
  2. import {t} from 'sentry/locale';
  3. import {Frame, PlatformType} from 'sentry/types';
  4. import {defined, objectIsEmpty} from 'sentry/utils';
  5. import {SymbolicatorStatus} from '../types';
  6. export function trimPackage(pkg: string) {
  7. const pieces = pkg.split(/^([a-z]:\\|\\\\)/i.test(pkg) ? '\\' : '/');
  8. const filename = pieces[pieces.length - 1] || pieces[pieces.length - 2] || pkg;
  9. return filename.replace(/\.(dylib|so|a|dll|exe)$/, '');
  10. }
  11. export function getPlatform(dataPlatform: PlatformType | null, platform: string) {
  12. // prioritize the frame platform but fall back to the platform
  13. // of the stack trace / exception
  14. return dataPlatform || platform;
  15. }
  16. export function getFrameHint(frame: Frame) {
  17. // returning [hintText, hintIcon]
  18. const {symbolicatorStatus} = frame;
  19. const func = frame.function || '<unknown>';
  20. // Custom color used to match adjacent text.
  21. const warningIcon = <IconQuestion size="xs" color={'#2c45a8' as any} />;
  22. const errorIcon = <IconWarning size="xs" color="red300" />;
  23. if (func.match(/^@objc\s/)) {
  24. return [t('Objective-C -> Swift shim frame'), warningIcon];
  25. }
  26. if (func.match(/^__?hidden#\d+/)) {
  27. return [t('Hidden function from bitcode build'), errorIcon];
  28. }
  29. if (!symbolicatorStatus && func === '<unknown>') {
  30. // Only render this if the event was not symbolicated.
  31. return [t('No function name was supplied by the client SDK.'), warningIcon];
  32. }
  33. if (
  34. func === '<unknown>' ||
  35. (func === '<redacted>' && symbolicatorStatus === SymbolicatorStatus.MISSING_SYMBOL)
  36. ) {
  37. switch (symbolicatorStatus) {
  38. case SymbolicatorStatus.MISSING_SYMBOL:
  39. return [t('The symbol was not found within the debug file.'), warningIcon];
  40. case SymbolicatorStatus.UNKNOWN_IMAGE:
  41. return [t('No image is specified for the address of the frame.'), warningIcon];
  42. case SymbolicatorStatus.MISSING:
  43. return [
  44. t('The debug file could not be retrieved from any of the sources.'),
  45. errorIcon,
  46. ];
  47. case SymbolicatorStatus.MALFORMED:
  48. return [t('The retrieved debug file could not be processed.'), errorIcon];
  49. default:
  50. }
  51. }
  52. if (func === '<redacted>') {
  53. return [t('Unknown system frame. Usually from beta SDKs'), warningIcon];
  54. }
  55. return [null, null];
  56. }
  57. export function isDotnet(platform: string) {
  58. // csharp platform represents .NET and can be F#, VB or any language targeting CLS (the Common Language Specification)
  59. return platform === 'csharp';
  60. }
  61. export function hasContextSource(frame: Frame) {
  62. return defined(frame.context) && !!frame.context.length;
  63. }
  64. export function hasContextVars(frame: Frame) {
  65. return !objectIsEmpty(frame.vars || {});
  66. }
  67. export function hasContextRegisters(registers: Record<string, string>) {
  68. return !objectIsEmpty(registers);
  69. }
  70. export function hasAssembly(frame: Frame, platform?: string) {
  71. return (
  72. isDotnet(getPlatform(frame.platform, platform ?? 'other')) && defined(frame.package)
  73. );
  74. }
  75. export function isExpandable({
  76. frame,
  77. registers,
  78. emptySourceNotation,
  79. platform,
  80. isOnlyFrame,
  81. }: {
  82. frame: Frame;
  83. registers: Record<string, string>;
  84. emptySourceNotation?: boolean;
  85. isOnlyFrame?: boolean;
  86. platform?: string;
  87. }) {
  88. return (
  89. (!isOnlyFrame && emptySourceNotation) ||
  90. hasContextSource(frame) ||
  91. hasContextVars(frame) ||
  92. hasContextRegisters(registers) ||
  93. hasAssembly(frame, platform)
  94. );
  95. }