eventErrors.spec.tsx 9.5 KB

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