eventErrors.spec.tsx 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. import {Event as EventFixture} from 'sentry-fixture/event';
  2. import {render, screen, userEvent, within} from 'sentry-test/reactTestingLibrary';
  3. import {textWithMarkupMatcher} from 'sentry-test/utils';
  4. import {EventErrors} from 'sentry/components/events/eventErrors';
  5. import {
  6. GenericSchemaErrors,
  7. JavascriptProcessingErrors,
  8. } from 'sentry/constants/eventErrors';
  9. import {EntryType} from 'sentry/types';
  10. describe('EventErrors', () => {
  11. const defaultProps = {
  12. project: TestStubs.Project(),
  13. event: EventFixture(),
  14. isShare: false,
  15. };
  16. beforeEach(() => {
  17. jest.resetAllMocks();
  18. MockApiClient.clearMockResponses();
  19. });
  20. it('does not render anything when no errors', () => {
  21. const {container} = render(<EventErrors {...defaultProps} />);
  22. expect(container).toBeEmptyDOMElement();
  23. });
  24. it('renders with errors in event', async () => {
  25. const eventWithErrors = EventFixture({
  26. errors: [
  27. {
  28. type: 'invalid_data',
  29. data: {
  30. name: 'logentry',
  31. },
  32. message: 'no message present',
  33. },
  34. {
  35. type: 'invalid_data',
  36. data: {
  37. name: 'breadcrumbs.values.2.data',
  38. },
  39. message: 'expected an object',
  40. },
  41. ],
  42. });
  43. render(<EventErrors {...defaultProps} event={eventWithErrors} />);
  44. await userEvent.click(
  45. screen.getByText(/there were 2 problems processing this event/i)
  46. );
  47. const errorItems = screen.getAllByTestId('event-error-item');
  48. expect(errorItems).toHaveLength(2);
  49. expect(within(errorItems[0]).getByText('logentry')).toBeInTheDocument();
  50. expect(
  51. within(errorItems[1]).getByText('breadcrumbs.values.2.data')
  52. ).toBeInTheDocument();
  53. });
  54. it('does not render hidden cocoa errors', async () => {
  55. const eventWithErrors = EventFixture({
  56. errors: [
  57. {
  58. type: 'not_invalid_data',
  59. data: {
  60. name: 'logentry',
  61. },
  62. message: 'no message present',
  63. },
  64. {
  65. type: 'invalid_data',
  66. data: {
  67. name: 'contexts.trace.sampled',
  68. },
  69. message: 'expected an object',
  70. },
  71. ],
  72. sdk: {
  73. name: 'sentry.cocoa',
  74. version: '8.7.3',
  75. },
  76. });
  77. render(<EventErrors {...defaultProps} event={eventWithErrors} />);
  78. await userEvent.click(screen.getByText(/there was 1 problem processing this event/i));
  79. const errorItem = screen.getByTestId('event-error-item');
  80. expect(errorItem).toBeInTheDocument();
  81. expect(within(errorItem).getByText('logentry')).toBeInTheDocument();
  82. });
  83. it('hides source map not found error', () => {
  84. const eventWithDifferentDist = EventFixture({
  85. errors: [
  86. {
  87. type: JavascriptProcessingErrors.JS_MISSING_SOURCE,
  88. },
  89. ],
  90. });
  91. render(<EventErrors {...defaultProps} event={eventWithDifferentDist} />);
  92. expect(screen.queryByText(/problem processing this event/i)).not.toBeInTheDocument();
  93. });
  94. it('hides event error that is hidden', () => {
  95. const eventWithUnknownError = EventFixture({
  96. errors: [
  97. {
  98. type: GenericSchemaErrors.UNKNOWN_ERROR,
  99. },
  100. ],
  101. });
  102. render(<EventErrors {...defaultProps} event={eventWithUnknownError} />);
  103. expect(screen.queryByText(/problem processing this event/i)).not.toBeInTheDocument();
  104. });
  105. describe('proguard errors', () => {
  106. beforeEach(() => {
  107. MockApiClient.addMockResponse({
  108. url: `/projects/org-slug/project-slug/files/dsyms/`,
  109. body: [],
  110. });
  111. });
  112. const proGuardUuid = 'a59c8fcc-2f27-49f8-af9e-02661fc3e8d7';
  113. it('displays missing mapping file with debugmeta but no event error', async () => {
  114. const eventWithDebugMeta = EventFixture({
  115. platform: 'java',
  116. entries: [
  117. {
  118. type: EntryType.DEBUGMETA,
  119. data: {
  120. images: [{type: 'proguard', uuid: proGuardUuid}],
  121. },
  122. },
  123. ],
  124. });
  125. render(<EventErrors {...defaultProps} event={eventWithDebugMeta} />);
  126. await userEvent.click(
  127. await screen.findByText(/there was 1 problem processing this event/i)
  128. );
  129. const errorItem = screen.getByTestId('event-error-item');
  130. expect(errorItem).toBeInTheDocument();
  131. expect(
  132. within(errorItem).getByText('A proguard mapping file was missing.')
  133. ).toBeInTheDocument();
  134. });
  135. it('displays missing mapping file with debugmeta and matching event error', async () => {
  136. const eventWithDebugMeta = EventFixture({
  137. platform: 'java',
  138. entries: [
  139. {
  140. type: EntryType.DEBUGMETA,
  141. data: {
  142. images: [{type: 'proguard', uuid: proGuardUuid}],
  143. },
  144. },
  145. ],
  146. errors: [
  147. {
  148. type: 'proguard_missing_mapping',
  149. message: 'A proguard mapping file was missing.',
  150. data: {mapping_uuid: proGuardUuid},
  151. },
  152. ],
  153. });
  154. render(<EventErrors {...defaultProps} event={eventWithDebugMeta} />);
  155. await userEvent.click(
  156. await screen.findByText(/there was 1 problem processing this event/i)
  157. );
  158. const errorItem = screen.getByTestId('event-error-item');
  159. expect(errorItem).toBeInTheDocument();
  160. expect(
  161. within(errorItem).getByText('A proguard mapping file was missing.')
  162. ).toBeInTheDocument();
  163. });
  164. describe('ProGuard Plugin seems to not be correctly configured', function () {
  165. it('find minified data in the exception entry', async function () {
  166. const newEvent = EventFixture({
  167. platform: 'java',
  168. entries: [
  169. {
  170. type: 'exception',
  171. data: {
  172. values: [
  173. {
  174. stacktrace: {
  175. frames: [
  176. {
  177. function: null,
  178. colNo: null,
  179. vars: {},
  180. symbol: null,
  181. module: 'a.$a.a.a',
  182. },
  183. ],
  184. framesOmitted: null,
  185. registers: null,
  186. hasSystemFrames: false,
  187. },
  188. module: null,
  189. rawStacktrace: null,
  190. mechanism: null,
  191. threadId: null,
  192. value: 'Unexpected token else',
  193. type: 'SyntaxError',
  194. },
  195. ],
  196. excOmitted: null,
  197. hasSystemFrames: false,
  198. },
  199. },
  200. ],
  201. });
  202. render(<EventErrors {...defaultProps} event={newEvent} />);
  203. await userEvent.click(
  204. await screen.findByText(/there was 1 problem processing this event/i)
  205. );
  206. const errorItem = screen.getByTestId('event-error-item');
  207. expect(errorItem).toBeInTheDocument();
  208. expect(
  209. within(errorItem).getByText(
  210. textWithMarkupMatcher(
  211. 'Some frames appear to be minified. Did you configure the Sentry Gradle Plugin?'
  212. )
  213. )
  214. ).toBeInTheDocument();
  215. });
  216. it('find minified data in the threads entry', async function () {
  217. const newEvent = EventFixture({
  218. platform: 'java',
  219. entries: [
  220. {
  221. type: 'exception',
  222. data: {
  223. values: [
  224. {
  225. stacktrace: {
  226. frames: [
  227. {
  228. function: null,
  229. colNo: null,
  230. vars: {},
  231. symbol: null,
  232. module: 'a.$a.a.a',
  233. },
  234. ],
  235. framesOmitted: null,
  236. registers: null,
  237. hasSystemFrames: false,
  238. },
  239. module: null,
  240. rawStacktrace: null,
  241. mechanism: null,
  242. threadId: null,
  243. value: 'Unexpected token else',
  244. type: 'SyntaxError',
  245. },
  246. ],
  247. excOmitted: null,
  248. hasSystemFrames: false,
  249. },
  250. },
  251. {
  252. type: 'threads',
  253. data: {
  254. values: [
  255. {
  256. stacktrace: {
  257. frames: [
  258. {
  259. function: 'start',
  260. package: 'libdyld.dylib',
  261. module: 'a.$a.a.a',
  262. },
  263. {
  264. function: 'main',
  265. package: 'iOS-Swift',
  266. module: '',
  267. },
  268. ],
  269. },
  270. },
  271. ],
  272. },
  273. },
  274. ],
  275. });
  276. render(<EventErrors {...defaultProps} event={newEvent} />);
  277. await userEvent.click(
  278. await screen.findByText(/there was 1 problem processing this event/i)
  279. );
  280. const errorItem = screen.getByTestId('event-error-item');
  281. expect(errorItem).toBeInTheDocument();
  282. expect(
  283. within(errorItem).getByText(
  284. textWithMarkupMatcher(
  285. 'Some frames appear to be minified. Did you configure the Sentry Gradle Plugin?'
  286. )
  287. )
  288. ).toBeInTheDocument();
  289. });
  290. });
  291. });
  292. });