@openobserve/browser-core 0.3.2 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/cjs/boot/init.js +1 -1
  2. package/cjs/domain/configuration/endpointBuilder.js +1 -1
  3. package/cjs/domain/tags.js +1 -1
  4. package/cjs/domain/telemetry/telemetry.js +1 -1
  5. package/cjs/domain/telemetry/telemetryEvent.types.d.ts +1 -1
  6. package/esm/boot/init.js +1 -1
  7. package/esm/domain/configuration/endpointBuilder.js +1 -1
  8. package/esm/domain/tags.js +1 -1
  9. package/esm/domain/telemetry/telemetry.js +1 -1
  10. package/esm/domain/telemetry/telemetryEvent.types.d.ts +1 -1
  11. package/package.json +2 -2
  12. package/src/domain/telemetry/telemetryEvent.types.ts +1 -1
  13. package/src/boot/displayAlreadyInitializedError.spec.ts +0 -18
  14. package/src/boot/init.spec.ts +0 -50
  15. package/src/browser/addEventListener.spec.ts +0 -141
  16. package/src/browser/cookie.spec.ts +0 -53
  17. package/src/browser/fetchObservable.spec.ts +0 -334
  18. package/src/browser/pageMayExitObservable.spec.ts +0 -56
  19. package/src/browser/xhrObservable.spec.ts +0 -405
  20. package/src/domain/allowedTrackingOrigins.spec.ts +0 -210
  21. package/src/domain/bufferedData.spec.ts +0 -34
  22. package/src/domain/configuration/configuration.spec.ts +0 -236
  23. package/src/domain/configuration/endpointBuilder.spec.ts +0 -173
  24. package/src/domain/configuration/transportConfiguration.spec.ts +0 -130
  25. package/src/domain/connectivity/connectivity.spec.ts +0 -50
  26. package/src/domain/console/consoleObservable.spec.ts +0 -151
  27. package/src/domain/context/contextManager.spec.ts +0 -152
  28. package/src/domain/context/contextUtils.spec.ts +0 -26
  29. package/src/domain/context/storeContextManager.spec.ts +0 -103
  30. package/src/domain/contexts/accountContext.spec.ts +0 -99
  31. package/src/domain/contexts/globalContext.spec.ts +0 -88
  32. package/src/domain/contexts/userContext.spec.ts +0 -156
  33. package/src/domain/error/error.spec.ts +0 -294
  34. package/src/domain/error/trackRuntimeError.spec.ts +0 -343
  35. package/src/domain/eventRateLimiter/createEventRateLimiter.spec.ts +0 -119
  36. package/src/domain/extension/extensionUtils.spec.ts +0 -47
  37. package/src/domain/report/reportObservable.spec.ts +0 -71
  38. package/src/domain/session/oldCookiesMigration.spec.ts +0 -76
  39. package/src/domain/session/sessionManager.spec.ts +0 -684
  40. package/src/domain/session/sessionState.spec.ts +0 -88
  41. package/src/domain/session/sessionStore.spec.ts +0 -647
  42. package/src/domain/session/sessionStoreOperations.spec.ts +0 -234
  43. package/src/domain/session/storeStrategies/sessionInCookie.spec.ts +0 -228
  44. package/src/domain/session/storeStrategies/sessionInLocalStorage.spec.ts +0 -75
  45. package/src/domain/synthetics/syntheticsWorkerValues.spec.ts +0 -82
  46. package/src/domain/tags.spec.ts +0 -74
  47. package/src/domain/telemetry/telemetry.spec.ts +0 -494
  48. package/src/domain/trackingConsent.spec.ts +0 -44
  49. package/src/tools/abstractHooks.spec.ts +0 -76
  50. package/src/tools/abstractLifeCycle.spec.ts +0 -46
  51. package/src/tools/boundedBuffer.spec.ts +0 -40
  52. package/src/tools/catchUserErrors.spec.ts +0 -20
  53. package/src/tools/encoder.spec.ts +0 -112
  54. package/src/tools/experimentalFeatures.spec.ts +0 -60
  55. package/src/tools/getZoneJsOriginalValue.spec.ts +0 -36
  56. package/src/tools/instrumentMethod.spec.ts +0 -381
  57. package/src/tools/matchOption.spec.ts +0 -41
  58. package/src/tools/mergeInto.spec.ts +0 -198
  59. package/src/tools/monitor.spec.ts +0 -172
  60. package/src/tools/observable.spec.ts +0 -259
  61. package/src/tools/queueMicrotask.spec.ts +0 -24
  62. package/src/tools/readBytesFromStream.spec.ts +0 -62
  63. package/src/tools/requestIdleCallback.spec.ts +0 -65
  64. package/src/tools/serialisation/jsonStringify.spec.ts +0 -76
  65. package/src/tools/serialisation/sanitize.spec.ts +0 -284
  66. package/src/tools/stackTrace/capturedExceptions.specHelper.ts +0 -316
  67. package/src/tools/stackTrace/computeStackTrace.spec.ts +0 -1007
  68. package/src/tools/stackTrace/handlingStack.spec.ts +0 -20
  69. package/src/tools/taskQueue.spec.ts +0 -60
  70. package/src/tools/timer.spec.ts +0 -76
  71. package/src/tools/utils/browserDetection.spec.ts +0 -120
  72. package/src/tools/utils/byteUtils.spec.ts +0 -29
  73. package/src/tools/utils/functionUtils.spec.ts +0 -229
  74. package/src/tools/utils/numberUtils.spec.ts +0 -27
  75. package/src/tools/utils/stringUtils.spec.ts +0 -74
  76. package/src/tools/utils/typeUtils.spec.ts +0 -25
  77. package/src/tools/utils/urlPolyfill.spec.ts +0 -55
  78. package/src/tools/valueHistory.spec.ts +0 -180
  79. package/src/transport/batch.spec.ts +0 -261
  80. package/src/transport/eventBridge.spec.ts +0 -90
  81. package/src/transport/flushController.spec.ts +0 -267
  82. package/src/transport/httpRequest.spec.ts +0 -400
  83. package/src/transport/sendWithRetryStrategy.spec.ts +0 -393
@@ -1,1007 +0,0 @@
1
- import { isSafari } from '../utils/browserDetection'
2
- import * as CapturedExceptions from './capturedExceptions.specHelper'
3
- import { computeStackTrace } from './computeStackTrace'
4
-
5
- describe('computeStackTrace', () => {
6
- it('should not remove anonymous functions from the stack', () => {
7
- // mock up an error object with a stack trace that includes both
8
- // named functions and anonymous functions
9
- const stack = `
10
- Error:
11
- at new <anonymous> (http://example.com/js/test.js:63:1)
12
- at namedFunc0 (http://example.com/js/script.js:10:2)
13
- at http://example.com/js/test.js:65:10
14
- at namedFunc2 (http://example.com/js/script.js:20:5)
15
- at http://example.com/js/test.js:67:5
16
- at namedFunc4 (http://example.com/js/script.js:100001:10002)`
17
- const mockErr: any = { stack }
18
- const stackFrames = computeStackTrace(mockErr)
19
-
20
- expect(stackFrames.stack[0].func).toEqual('new <anonymous>')
21
- expect(stackFrames.stack[0].url).toEqual('http://example.com/js/test.js')
22
- expect(stackFrames.stack[0].line).toEqual(63)
23
- expect(stackFrames.stack[0].column).toEqual(1)
24
- expect(stackFrames.stack[1].func).toEqual('namedFunc0')
25
- expect(stackFrames.stack[1].url).toEqual('http://example.com/js/script.js')
26
- expect(stackFrames.stack[1].line).toEqual(10)
27
- expect(stackFrames.stack[1].column).toEqual(2)
28
-
29
- expect(stackFrames.stack[2].func).toEqual('?')
30
- expect(stackFrames.stack[2].url).toEqual('http://example.com/js/test.js')
31
- expect(stackFrames.stack[2].line).toEqual(65)
32
- expect(stackFrames.stack[2].column).toEqual(10)
33
-
34
- expect(stackFrames.stack[3].func).toEqual('namedFunc2')
35
- expect(stackFrames.stack[3].url).toEqual('http://example.com/js/script.js')
36
- expect(stackFrames.stack[3].line).toEqual(20)
37
- expect(stackFrames.stack[3].column).toEqual(5)
38
-
39
- expect(stackFrames.stack[4].func).toEqual('?')
40
- expect(stackFrames.stack[4].url).toEqual('http://example.com/js/test.js')
41
- expect(stackFrames.stack[4].line).toEqual(67)
42
- expect(stackFrames.stack[4].column).toEqual(5)
43
-
44
- expect(stackFrames.stack[5].func).toEqual('namedFunc4')
45
- expect(stackFrames.stack[5].url).toEqual('http://example.com/js/script.js')
46
- expect(stackFrames.stack[5].line).toEqual(100001)
47
- expect(stackFrames.stack[5].column).toEqual(10002)
48
- })
49
-
50
- it('should handle eval/anonymous strings in Chrome 46', () => {
51
- const stack = `
52
- ReferenceError: baz is not defined
53
- at bar (http://example.com/js/test.js:19:7)
54
- at foo (http://example.com/js/test.js:23:7)
55
- at eval (eval at <anonymous> (http://example.com/js/test.js:26:5)).toEqual(<anonymous>:1:26)
56
- `
57
-
58
- const mockErr: any = { stack }
59
- const stackFrames = computeStackTrace(mockErr)
60
-
61
- expect(stackFrames.stack[0].func).toEqual('bar')
62
- expect(stackFrames.stack[0].url).toEqual('http://example.com/js/test.js')
63
- expect(stackFrames.stack[0].line).toEqual(19)
64
- expect(stackFrames.stack[0].column).toEqual(7)
65
-
66
- expect(stackFrames.stack[1].func).toEqual('foo')
67
- expect(stackFrames.stack[1].url).toEqual('http://example.com/js/test.js')
68
- expect(stackFrames.stack[1].line).toEqual(23)
69
- expect(stackFrames.stack[1].column).toEqual(7)
70
-
71
- expect(stackFrames.stack[2].func).toEqual('eval')
72
- // TODO: fix nested evals
73
- expect(stackFrames.stack[2].url).toEqual('http://example.com/js/test.js')
74
- expect(stackFrames.stack[2].line).toEqual(26)
75
- expect(stackFrames.stack[2].column).toEqual(5)
76
- })
77
-
78
- const stackStr = `
79
- Error: foo
80
- at <anonymous>:2:11
81
- at Object.InjectedScript._evaluateOn (<anonymous>:904:140)
82
- at Object.InjectedScript._evaluateAndWrap (<anonymous>:837:34)
83
- at Object.InjectedScript.evaluate (<anonymous>:693:21)`
84
-
85
- it('should handle a native error object', () => {
86
- const ex = new Error('test')
87
- const stack = computeStackTrace(ex)
88
- expect(stack.name).toEqual('Error')
89
- expect(stack.message).toEqual('test')
90
- })
91
-
92
- it('should handle a native error object stack from Chrome', () => {
93
- const mockErr = { message: 'foo', name: 'Error', stack: stackStr }
94
- const stackFrames = computeStackTrace(mockErr)
95
-
96
- expect(stackFrames.stack[0].url).toEqual('<anonymous>')
97
- })
98
-
99
- it('should handle edge case values', () => {
100
- expect(computeStackTrace({ message: { foo: 'bar' } }).message).toBeUndefined()
101
- expect(computeStackTrace({ name: { foo: 'bar' } }).name).toBeUndefined()
102
- expect(computeStackTrace({ message: { foo: 'bar' }, stack: stackStr }).message).toBeUndefined()
103
- expect(computeStackTrace({ name: { foo: 'bar' }, stack: stackStr }).name).toBeUndefined()
104
- expect(computeStackTrace(2).message).toBeUndefined()
105
- expect(computeStackTrace({ foo: 'bar' }).message).toBeUndefined()
106
- expect(computeStackTrace(undefined).message).toBeUndefined()
107
- expect(computeStackTrace(null).message).toBeUndefined()
108
- })
109
-
110
- it('should get the order of functions called right', () => {
111
- if (isSafari()) {
112
- pending()
113
- }
114
- function foo() {
115
- return bar()
116
- }
117
-
118
- function bar() {
119
- return baz()
120
- }
121
-
122
- function baz() {
123
- return computeStackTrace(new Error())
124
- }
125
-
126
- const trace = foo()
127
- const expected = ['baz', 'bar', 'foo']
128
-
129
- for (let i = 0; i <= 2; i += 1) {
130
- expect(trace.stack[i].func).toEqual(expected[i])
131
- }
132
- })
133
-
134
- it('should parse Safari 6 error', () => {
135
- const stackFrames = computeStackTrace(CapturedExceptions.SAFARI_6)
136
-
137
- expect(stackFrames.stack.length).toEqual(4)
138
- expect(stackFrames.stack[0]).toEqual({
139
- args: [],
140
- column: undefined,
141
- func: '?',
142
- line: 48,
143
- url: 'http://path/to/file.js',
144
- })
145
- expect(stackFrames.stack[1]).toEqual({
146
- args: [],
147
- column: undefined,
148
- func: 'dumpException3',
149
- line: 52,
150
- url: 'http://path/to/file.js',
151
- })
152
- expect(stackFrames.stack[2]).toEqual({
153
- args: [],
154
- column: undefined,
155
- func: 'onclick',
156
- line: 82,
157
- url: 'http://path/to/file.js',
158
- })
159
- expect(stackFrames.stack[3]).toEqual({
160
- args: [],
161
- column: undefined,
162
- func: '?',
163
- line: undefined,
164
- url: '[native code]',
165
- })
166
- })
167
-
168
- it('should parse Safari 7 error', () => {
169
- const stackFrames = computeStackTrace(CapturedExceptions.SAFARI_7)
170
-
171
- expect(stackFrames.stack.length).toEqual(3)
172
- expect(stackFrames.stack[0]).toEqual({ args: [], column: 22, func: '?', line: 48, url: 'http://path/to/file.js' })
173
- expect(stackFrames.stack[1]).toEqual({ args: [], column: 15, func: 'foo', line: 52, url: 'http://path/to/file.js' })
174
- expect(stackFrames.stack[2]).toEqual({
175
- args: [],
176
- column: 107,
177
- func: 'bar',
178
- line: 108,
179
- url: 'http://path/to/file.js',
180
- })
181
- })
182
-
183
- it('should parse Safari 8 error', () => {
184
- const stackFrames = computeStackTrace(CapturedExceptions.SAFARI_8)
185
-
186
- expect(stackFrames.stack.length).toEqual(3)
187
- expect(stackFrames.stack[0]).toEqual({ args: [], column: 22, func: '?', line: 47, url: 'http://path/to/file.js' })
188
- expect(stackFrames.stack[1]).toEqual({ args: [], column: 15, func: 'foo', line: 52, url: 'http://path/to/file.js' })
189
- expect(stackFrames.stack[2]).toEqual({
190
- args: [],
191
- column: 23,
192
- func: 'bar',
193
- line: 108,
194
- url: 'http://path/to/file.js',
195
- })
196
- })
197
-
198
- it('should parse Safari 8 eval error', () => {
199
- // TODO: Take into account the line and column properties
200
- // on the error object and use them for the first stack trace.
201
- const stackFrames = computeStackTrace(CapturedExceptions.SAFARI_8_EVAL)
202
-
203
- expect(stackFrames.stack.length).toEqual(3)
204
- expect(stackFrames.stack[0]).toEqual({
205
- args: [],
206
- column: undefined,
207
- func: 'eval',
208
- line: undefined,
209
- url: '[native code]',
210
- })
211
- expect(stackFrames.stack[1]).toEqual({ args: [], column: 21, func: 'foo', line: 58, url: 'http://path/to/file.js' })
212
- expect(stackFrames.stack[2]).toEqual({
213
- args: [],
214
- column: 91,
215
- func: 'bar',
216
- line: 109,
217
- url: 'http://path/to/file.js',
218
- })
219
- })
220
-
221
- it('should parse Firefox 3 error', () => {
222
- const stackFrames = computeStackTrace(CapturedExceptions.FIREFOX_3)
223
-
224
- expect(stackFrames.stack.length).toEqual(7)
225
- expect(stackFrames.stack[0]).toEqual({
226
- args: [],
227
- column: undefined,
228
- func: '?',
229
- line: 44,
230
- url: 'http://127.0.0.1:8000/js/stacktrace.js',
231
- })
232
- expect(stackFrames.stack[1]).toEqual({
233
- args: ['null'],
234
- column: undefined,
235
- func: '?',
236
- line: 31,
237
- url: 'http://127.0.0.1:8000/js/stacktrace.js',
238
- })
239
- expect(stackFrames.stack[2]).toEqual({
240
- args: [],
241
- column: undefined,
242
- func: 'printStackTrace',
243
- line: 18,
244
- url: 'http://127.0.0.1:8000/js/stacktrace.js',
245
- })
246
- expect(stackFrames.stack[3]).toEqual({
247
- args: ['1'],
248
- column: undefined,
249
- func: 'bar',
250
- line: 13,
251
- url: 'http://127.0.0.1:8000/js/file.js',
252
- })
253
- expect(stackFrames.stack[4]).toEqual({
254
- args: ['2'],
255
- column: undefined,
256
- func: 'bar',
257
- line: 16,
258
- url: 'http://127.0.0.1:8000/js/file.js',
259
- })
260
- expect(stackFrames.stack[5]).toEqual({
261
- args: [],
262
- column: undefined,
263
- func: 'foo',
264
- line: 20,
265
- url: 'http://127.0.0.1:8000/js/file.js',
266
- })
267
- expect(stackFrames.stack[6]).toEqual({
268
- args: [],
269
- column: undefined,
270
- func: '?',
271
- line: 24,
272
- url: 'http://127.0.0.1:8000/js/file.js',
273
- })
274
- })
275
-
276
- it('should parse Firefox 7 error', () => {
277
- const stackFrames = computeStackTrace(CapturedExceptions.FIREFOX_7)
278
-
279
- expect(stackFrames.stack.length).toEqual(7)
280
- expect(stackFrames.stack[0]).toEqual({
281
- args: [],
282
- column: undefined,
283
- func: '?',
284
- line: 44,
285
- url: 'file:///G:/js/stacktrace.js',
286
- })
287
- expect(stackFrames.stack[1]).toEqual({
288
- args: ['null'],
289
- column: undefined,
290
- func: '?',
291
- line: 31,
292
- url: 'file:///G:/js/stacktrace.js',
293
- })
294
- expect(stackFrames.stack[2]).toEqual({
295
- args: [],
296
- column: undefined,
297
- func: 'printStackTrace',
298
- line: 18,
299
- url: 'file:///G:/js/stacktrace.js',
300
- })
301
- expect(stackFrames.stack[3]).toEqual({
302
- args: ['1'],
303
- column: undefined,
304
- func: 'bar',
305
- line: 13,
306
- url: 'file:///G:/js/file.js',
307
- })
308
- expect(stackFrames.stack[4]).toEqual({
309
- args: ['2'],
310
- column: undefined,
311
- func: 'bar',
312
- line: 16,
313
- url: 'file:///G:/js/file.js',
314
- })
315
- expect(stackFrames.stack[5]).toEqual({
316
- args: [],
317
- column: undefined,
318
- func: 'foo',
319
- line: 20,
320
- url: 'file:///G:/js/file.js',
321
- })
322
- expect(stackFrames.stack[6]).toEqual({
323
- args: [],
324
- column: undefined,
325
- func: '?',
326
- line: 24,
327
- url: 'file:///G:/js/file.js',
328
- })
329
- })
330
-
331
- it('should parse Firefox 14 error', () => {
332
- const stackFrames = computeStackTrace(CapturedExceptions.FIREFOX_14)
333
-
334
- expect(stackFrames.stack.length).toEqual(3)
335
- expect(stackFrames.stack[0]).toEqual({
336
- args: [],
337
- column: undefined,
338
- func: '?',
339
- line: 48,
340
- url: 'http://path/to/file.js',
341
- })
342
- expect(stackFrames.stack[1]).toEqual({
343
- args: [],
344
- column: undefined,
345
- func: 'dumpException3',
346
- line: 52,
347
- url: 'http://path/to/file.js',
348
- })
349
- expect(stackFrames.stack[2]).toEqual({
350
- args: [],
351
- column: undefined,
352
- func: 'onclick',
353
- line: 1,
354
- url: 'http://path/to/file.js',
355
- })
356
- })
357
-
358
- it('should parse Firefox 31 error', () => {
359
- const stackFrames = computeStackTrace(CapturedExceptions.FIREFOX_31)
360
-
361
- expect(stackFrames.stack.length).toEqual(3)
362
- expect(stackFrames.stack[0]).toEqual({ args: [], column: 13, func: 'foo', line: 41, url: 'http://path/to/file.js' })
363
- expect(stackFrames.stack[1]).toEqual({ args: [], column: 1, func: 'bar', line: 1, url: 'http://path/to/file.js' })
364
- expect(stackFrames.stack[2]).toEqual({
365
- args: [],
366
- column: 1,
367
- func: '.plugin/e.fn[c]/<',
368
- line: 1,
369
- url: 'http://path/to/file.js',
370
- })
371
- })
372
-
373
- it('should parse Firefox 44 ns exceptions', () => {
374
- const stackFrames = computeStackTrace(CapturedExceptions.FIREFOX_44_NS_EXCEPTION)
375
-
376
- expect(stackFrames.stack.length).toEqual(4)
377
- expect(stackFrames.stack[0]).toEqual({
378
- args: [],
379
- column: 28,
380
- func: '[2]</Bar.prototype._baz/</<',
381
- line: 703,
382
- url: 'http://path/to/file.js',
383
- })
384
- expect(stackFrames.stack[1]).toEqual({
385
- args: [],
386
- column: 2,
387
- func: 'App.prototype.foo',
388
- line: 15,
389
- url: 'file:///path/to/file.js',
390
- })
391
- expect(stackFrames.stack[2]).toEqual({ args: [], column: 3, func: 'bar', line: 20, url: 'file:///path/to/file.js' })
392
- expect(stackFrames.stack[3]).toEqual({
393
- args: [],
394
- column: 1,
395
- func: '?',
396
- line: 23,
397
- url: 'file:///path/to/index.html',
398
- })
399
- })
400
-
401
- it('should parse Chrome error with no location', () => {
402
- const error = { stack: 'error\n at Array.forEach (native)' }
403
- const stackFrames = computeStackTrace(error as Error)
404
- expect(stackFrames.stack.length).toEqual(1)
405
- expect(stackFrames.stack[0]).toEqual({
406
- args: ['native'],
407
- column: undefined,
408
- func: 'Array.forEach',
409
- line: undefined,
410
- url: undefined,
411
- })
412
- })
413
-
414
- it('should parse Chrome error that only contain file name, with no path prefix', () => {
415
- const stack = `Error: RTE Simulation
416
- at foo$bar$oof$rab (events.cljs:1060:12)
417
- at func1$func2$func3$func4 (std_interceptors.js:128:19)
418
- at eval (std_interceptors.jsx:132:29)`
419
-
420
- const stackFrames = computeStackTrace({ stack } as Error)
421
- expect(stackFrames.stack.length).toEqual(3)
422
- expect(stackFrames.stack[0]).toEqual({
423
- args: [],
424
- column: 12,
425
- func: 'foo$bar$oof$rab',
426
- line: 1060,
427
- url: 'events.cljs',
428
- })
429
- expect(stackFrames.stack[1]).toEqual({
430
- args: [],
431
- column: 19,
432
- func: 'func1$func2$func3$func4',
433
- line: 128,
434
- url: 'std_interceptors.js',
435
- })
436
- expect(stackFrames.stack[2]).toEqual({ args: [], column: 29, func: 'eval', line: 132, url: 'std_interceptors.jsx' })
437
- })
438
-
439
- it('should not include error message into stacktrace ', () => {
440
- const stackFrames = computeStackTrace(new Error('bar@http://path/to/file.js:1:1'))
441
-
442
- expect(stackFrames.stack[0]?.url).not.toBe('http://path/to/file.js')
443
- })
444
-
445
- it('should parse Chrome anonymous function errors', () => {
446
- const stack = `Error: RTE Simulation
447
- at https://cloud.openobserve.ai/somefile.js:8489:191
448
- at chrome-extension://<id>/content/index.js:85:37379`
449
-
450
- const stackFrames = computeStackTrace({ stack } as Error)
451
- expect(stackFrames.stack.length).toEqual(2)
452
- expect(stackFrames.stack[0]).toEqual({
453
- args: [],
454
- column: 191,
455
- func: '?',
456
- line: 8489,
457
- url: 'https://cloud.openobserve.ai/somefile.js',
458
- })
459
- expect(stackFrames.stack[1]).toEqual({
460
- args: [],
461
- column: 37379,
462
- func: '?',
463
- line: 85,
464
- url: 'chrome-extension://<id>/content/index.js',
465
- })
466
- })
467
-
468
- it('should parse Chrome 15 error', () => {
469
- const stackFrames = computeStackTrace(CapturedExceptions.CHROME_15 as any)
470
-
471
- expect(stackFrames.stack.length).toEqual(4)
472
- expect(stackFrames.stack[0]).toEqual({ args: [], column: 17, func: 'bar', line: 13, url: 'http://path/to/file.js' })
473
- expect(stackFrames.stack[1]).toEqual({ args: [], column: 5, func: 'bar', line: 16, url: 'http://path/to/file.js' })
474
- expect(stackFrames.stack[2]).toEqual({ args: [], column: 5, func: 'foo', line: 20, url: 'http://path/to/file.js' })
475
- expect(stackFrames.stack[3]).toEqual({ args: [], column: 4, func: '?', line: 24, url: 'http://path/to/file.js' })
476
- })
477
-
478
- it('should parse Chrome 36 error with port numbers', () => {
479
- const stackFrames = computeStackTrace(CapturedExceptions.CHROME_36)
480
-
481
- expect(stackFrames.stack.length).toEqual(3)
482
- expect(stackFrames.stack[0]).toEqual({
483
- args: [],
484
- column: 27,
485
- func: 'dumpExceptionError',
486
- line: 41,
487
- url: 'http://localhost:8080/file.js',
488
- })
489
- expect(stackFrames.stack[1]).toEqual({
490
- args: [],
491
- column: 146,
492
- func: 'HTMLButtonElement.onclick',
493
- line: 107,
494
- url: 'http://localhost:8080/file.js',
495
- })
496
- expect(stackFrames.stack[2]).toEqual({
497
- args: [],
498
- column: 3651,
499
- func: 'I.e.fn.(anonymous function) [as index]',
500
- line: 10,
501
- url: 'http://localhost:8080/file.js',
502
- })
503
- })
504
-
505
- it('should parse Chrome error with webpack URLs', () => {
506
- const stackFrames = computeStackTrace(CapturedExceptions.CHROME_XX_WEBPACK)
507
-
508
- expect(stackFrames.stack.length).toEqual(4)
509
- expect(stackFrames.stack[0]).toEqual({
510
- args: [],
511
- column: 108,
512
- func: 'TESTTESTTEST.eval',
513
- line: 295,
514
- url: 'webpack:///./src/components/test/test.jsx?',
515
- })
516
- expect(stackFrames.stack[1]).toEqual({
517
- args: [],
518
- column: 32,
519
- func: 'TESTTESTTEST.render',
520
- line: 272,
521
- url: 'webpack:///./src/components/test/test.jsx?',
522
- })
523
- expect(stackFrames.stack[2]).toEqual({
524
- args: [],
525
- column: 31,
526
- func: 'TESTTESTTEST.tryRender',
527
- line: 34,
528
- url: 'webpack:///./~/react-transform-catch-errors/lib/index.js?',
529
- })
530
- expect(stackFrames.stack[3]).toEqual({
531
- args: [],
532
- column: 30,
533
- func: 'TESTTESTTEST.proxiedMethod',
534
- line: 44,
535
- url: 'webpack:///./~/react-proxy/modules/createPrototypeProxy.js?',
536
- })
537
- })
538
-
539
- it('should parse Electron schema with Chrome error', () => {
540
- const stackFrames = computeStackTrace(CapturedExceptions.ELECTRON)
541
-
542
- expect(stackFrames.stack.length).toEqual(3)
543
- expect(stackFrames.stack[0]).toEqual({
544
- args: [],
545
- column: 27,
546
- func: 'dumpExceptionError',
547
- line: 41,
548
- url: 'electron://-/file.js',
549
- })
550
- expect(stackFrames.stack[1]).toEqual({
551
- args: [],
552
- column: 146,
553
- func: 'HTMLButtonElement.onclick',
554
- line: 107,
555
- url: 'electron://-/file.js',
556
- })
557
- expect(stackFrames.stack[2]).toEqual({
558
- args: [],
559
- column: 3651,
560
- func: 'I.e.fn.(anonymous function) [as index]',
561
- line: 10,
562
- url: 'electron://-/file.js',
563
- })
564
- })
565
-
566
- it('should parse nested eval() from Chrome', () => {
567
- const stackFrames = computeStackTrace(CapturedExceptions.CHROME_48_EVAL)
568
-
569
- expect(stackFrames.stack.length).toEqual(5)
570
- expect(stackFrames.stack[0]).toEqual({
571
- args: [],
572
- column: 17,
573
- func: 'baz',
574
- line: 21,
575
- url: 'http://localhost:8080/file.js',
576
- })
577
- expect(stackFrames.stack[1]).toEqual({
578
- args: [],
579
- column: 17,
580
- func: 'foo',
581
- line: 21,
582
- url: 'http://localhost:8080/file.js',
583
- })
584
- expect(stackFrames.stack[2]).toEqual({
585
- args: [],
586
- column: 17,
587
- func: 'eval',
588
- line: 21,
589
- url: 'http://localhost:8080/file.js',
590
- })
591
- expect(stackFrames.stack[3]).toEqual({
592
- args: [],
593
- column: 17,
594
- func: 'Object.speak',
595
- line: 21,
596
- url: 'http://localhost:8080/file.js',
597
- })
598
- expect(stackFrames.stack[4]).toEqual({
599
- args: [],
600
- column: 13,
601
- func: '?',
602
- line: 31,
603
- url: 'http://localhost:8080/file.js',
604
- })
605
- })
606
-
607
- it('should parse Chrome error with blob URLs', () => {
608
- const stackFrames = computeStackTrace(CapturedExceptions.CHROME_48_BLOB)
609
-
610
- expect(stackFrames.stack.length).toEqual(7)
611
- expect(stackFrames.stack[1]).toEqual({
612
- args: [],
613
- column: 29146,
614
- func: 's',
615
- line: 31,
616
- url: 'blob:http%3A//localhost%3A8080/abfc40e9-4742-44ed-9dcd-af8f99a29379',
617
- })
618
- expect(stackFrames.stack[2]).toEqual({
619
- args: [],
620
- column: 30039,
621
- func: 'Object.d [as add]',
622
- line: 31,
623
- url: 'blob:http%3A//localhost%3A8080/abfc40e9-4742-44ed-9dcd-af8f99a29379',
624
- })
625
- expect(stackFrames.stack[3]).toEqual({
626
- args: [],
627
- column: 10978,
628
- func: '?',
629
- line: 15,
630
- url: 'blob:http%3A//localhost%3A8080/d4eefe0f-361a-4682-b217-76587d9f712a',
631
- })
632
- expect(stackFrames.stack[4]).toEqual({
633
- args: [],
634
- column: 6911,
635
- func: '?',
636
- line: 1,
637
- url: 'blob:http%3A//localhost%3A8080/abfc40e9-4742-44ed-9dcd-af8f99a29379',
638
- })
639
- expect(stackFrames.stack[5]).toEqual({
640
- args: [],
641
- column: 3019,
642
- func: 'n.fire',
643
- line: 7,
644
- url: 'blob:http%3A//localhost%3A8080/abfc40e9-4742-44ed-9dcd-af8f99a29379',
645
- })
646
- expect(stackFrames.stack[6]).toEqual({
647
- args: [],
648
- column: 2863,
649
- func: 'n.handle',
650
- line: 7,
651
- url: 'blob:http%3A//localhost%3A8080/abfc40e9-4742-44ed-9dcd-af8f99a29379',
652
- })
653
- })
654
-
655
- it('should parse errors from Chrome Snippets', () => {
656
- const stackFrames = computeStackTrace(CapturedExceptions.CHROME_111_SNIPPET)
657
-
658
- expect(stackFrames.stack.length).toEqual(1)
659
- expect(stackFrames.stack[0]).toEqual({ args: [], column: 13, func: '?', line: 1, url: 'snippet:///snippet_file' })
660
- })
661
-
662
- it('should parse empty IE 9 error', () => {
663
- const stackFrames = computeStackTrace(CapturedExceptions.IE_9)
664
-
665
- if (stackFrames.stack) {
666
- expect(stackFrames.stack.length).toEqual(0)
667
- }
668
- })
669
-
670
- it('should parse IE 10 error', () => {
671
- const stackFrames = computeStackTrace(CapturedExceptions.IE_10 as any)
672
-
673
- expect(stackFrames.stack.length).toEqual(3)
674
- // TODO: func should be normalized
675
- expect(stackFrames.stack[0]).toEqual({
676
- args: [],
677
- column: 13,
678
- func: 'Anonymous function',
679
- line: 48,
680
- url: 'http://path/to/file.js',
681
- })
682
- expect(stackFrames.stack[1]).toEqual({ args: [], column: 9, func: 'foo', line: 46, url: 'http://path/to/file.js' })
683
- expect(stackFrames.stack[2]).toEqual({ args: [], column: 1, func: 'bar', line: 82, url: 'http://path/to/file.js' })
684
- })
685
-
686
- it('should parse IE 11 error', () => {
687
- const stackFrames = computeStackTrace(CapturedExceptions.IE_11)
688
-
689
- expect(stackFrames.stack.length).toEqual(3)
690
- // TODO: func should be normalized
691
- expect(stackFrames.stack[0]).toEqual({
692
- args: [],
693
- column: 21,
694
- func: 'Anonymous function',
695
- line: 47,
696
- url: 'http://path/to/file.js',
697
- })
698
- expect(stackFrames.stack[1]).toEqual({ args: [], column: 13, func: 'foo', line: 45, url: 'http://path/to/file.js' })
699
- expect(stackFrames.stack[2]).toEqual({ args: [], column: 1, func: 'bar', line: 108, url: 'http://path/to/file.js' })
700
- })
701
-
702
- it('should parse IE 11 eval error', () => {
703
- const stackFrames = computeStackTrace(CapturedExceptions.IE_11_EVAL)
704
-
705
- expect(stackFrames.stack.length).toEqual(3)
706
- expect(stackFrames.stack[0]).toEqual({ args: [], column: 1, func: 'eval code', line: 1, url: 'eval code' })
707
- expect(stackFrames.stack[1]).toEqual({ args: [], column: 17, func: 'foo', line: 58, url: 'http://path/to/file.js' })
708
- expect(stackFrames.stack[2]).toEqual({ args: [], column: 1, func: 'bar', line: 109, url: 'http://path/to/file.js' })
709
- })
710
-
711
- it('should parse Opera 25 error', () => {
712
- const stackFrames = computeStackTrace(CapturedExceptions.OPERA_25)
713
-
714
- expect(stackFrames.stack.length).toEqual(3)
715
- expect(stackFrames.stack[0]).toEqual({ args: [], column: 22, func: '?', line: 47, url: 'http://path/to/file.js' })
716
- expect(stackFrames.stack[1]).toEqual({ args: [], column: 15, func: 'foo', line: 52, url: 'http://path/to/file.js' })
717
- expect(stackFrames.stack[2]).toEqual({
718
- args: [],
719
- column: 168,
720
- func: 'bar',
721
- line: 108,
722
- url: 'http://path/to/file.js',
723
- })
724
- })
725
-
726
- it('should parse PhantomJS 1.19 error', () => {
727
- const stackFrames = computeStackTrace(CapturedExceptions.PHANTOMJS_1_19 as Error)
728
-
729
- expect(stackFrames.stack.length).toEqual(3)
730
- expect(stackFrames.stack[0]).toEqual({
731
- args: [],
732
- column: undefined,
733
- func: '?',
734
- line: 878,
735
- url: 'file:///path/to/file.js',
736
- })
737
- expect(stackFrames.stack[1]).toEqual({
738
- args: [],
739
- column: undefined,
740
- func: 'foo',
741
- line: 4283,
742
- url: 'http://path/to/file.js',
743
- })
744
- expect(stackFrames.stack[2]).toEqual({
745
- args: [],
746
- column: undefined,
747
- func: '?',
748
- line: 4287,
749
- url: 'http://path/to/file.js',
750
- })
751
- })
752
-
753
- it('should parse Firefox errors with resource: URLs', () => {
754
- const stackFrames = computeStackTrace(CapturedExceptions.FIREFOX_50_RESOURCE_URL)
755
-
756
- expect(stackFrames.stack.length).toEqual(3)
757
- expect(stackFrames.stack[0]).toEqual({
758
- args: [],
759
- column: 16,
760
- func: 'render',
761
- line: 5529,
762
- url: 'resource://path/data/content/bundle.js',
763
- })
764
- })
765
-
766
- it('should parse Firefox errors with eval URLs', () => {
767
- const stackFrames = computeStackTrace(CapturedExceptions.FIREFOX_43_EVAL as any)
768
-
769
- expect(stackFrames.stack.length).toEqual(5)
770
- expect(stackFrames.stack[0]).toEqual({
771
- args: [],
772
- column: undefined,
773
- func: 'baz',
774
- line: 26,
775
- url: 'http://localhost:8080/file.js',
776
- })
777
- expect(stackFrames.stack[1]).toEqual({
778
- args: [],
779
- column: undefined,
780
- func: 'foo',
781
- line: 26,
782
- url: 'http://localhost:8080/file.js',
783
- })
784
- expect(stackFrames.stack[2]).toEqual({
785
- args: [],
786
- column: undefined,
787
- func: '?',
788
- line: 26,
789
- url: 'http://localhost:8080/file.js',
790
- })
791
- expect(stackFrames.stack[3]).toEqual({
792
- args: [],
793
- column: 17,
794
- func: 'speak',
795
- line: 26,
796
- url: 'http://localhost:8080/file.js',
797
- })
798
- expect(stackFrames.stack[4]).toEqual({
799
- args: [],
800
- column: 9,
801
- func: '?',
802
- line: 33,
803
- url: 'http://localhost:8080/file.js',
804
- })
805
- })
806
-
807
- it('should parse React Native errors on Android', () => {
808
- const stackFrames = computeStackTrace(CapturedExceptions.ANDROID_REACT_NATIVE)
809
-
810
- expect(stackFrames.stack.length).toEqual(8)
811
- expect(stackFrames.stack[0]).toEqual({
812
- args: [],
813
- column: 24,
814
- func: 'render',
815
- line: 78,
816
- url: '/home/username/sample-workspace/sampleapp.collect.react/src/components/GpsMonitorScene.js',
817
- })
818
- expect(stackFrames.stack[7]).toEqual({
819
- args: [],
820
- column: 41,
821
- func: 'this',
822
- line: 74,
823
- url: '/home/username/sample-workspace/sampleapp.collect.react/node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNativeBaseComponent.js',
824
- })
825
- })
826
-
827
- it('should parse React Native errors on Android Production', () => {
828
- const stackFrames = computeStackTrace(CapturedExceptions.ANDROID_REACT_NATIVE_PROD)
829
-
830
- expect(stackFrames.stack.length).toEqual(37)
831
- expect(stackFrames.stack[0]).toEqual({
832
- args: [],
833
- column: 1917,
834
- func: 'value',
835
- line: 12,
836
- url: 'index.android.bundle',
837
- })
838
- expect(stackFrames.stack[35]).toEqual({
839
- args: [],
840
- column: 927,
841
- func: 'value',
842
- line: 29,
843
- url: 'index.android.bundle',
844
- })
845
- expect(stackFrames.stack[36]).toEqual({
846
- args: [],
847
- column: undefined,
848
- func: '?',
849
- line: undefined,
850
- url: '[native code]',
851
- })
852
- })
853
-
854
- it('should parse iOS capacitor', () => {
855
- const stackFrames = computeStackTrace(CapturedExceptions.IOS_CAPACITOR)
856
-
857
- expect(stackFrames.stack.length).toEqual(2)
858
- expect(stackFrames.stack[0]).toEqual({
859
- args: [],
860
- column: 99546,
861
- func: '?',
862
- line: 34,
863
- url: 'capacitor://localhost/media/dist/bundle.js',
864
- })
865
- expect(stackFrames.stack[1]).toEqual({
866
- args: [],
867
- column: 47950,
868
- func: 'r',
869
- line: 34,
870
- url: 'capacitor://localhost/media/dist/bundle.js',
871
- })
872
- })
873
-
874
- it('should parse Safari WebAssembly stack frames', () => {
875
- const wasmStack = `
876
- RuntimeError: Out of bounds memory access
877
- myModule.wasm-function[crashHandler]@[wasm code]
878
- <?>.wasm-function[42]@[wasm code]
879
- handleError@http://192.168.1.113:3000/:98:25
880
- @http://192.168.1.113:3000/:113:32
881
- `
882
- const mockErr = { message: 'Out of bounds memory access', name: 'RuntimeError', stack: wasmStack }
883
- const stackFrames = computeStackTrace(mockErr)
884
-
885
- expect(stackFrames.stack.length).toBe(4)
886
-
887
- expect(stackFrames.stack[0]).toEqual({
888
- args: [],
889
- func: 'myModule.wasm-function[crashHandler]',
890
- url: '[wasm code]',
891
- column: undefined,
892
- line: undefined,
893
- })
894
-
895
- expect(stackFrames.stack[1]).toEqual({
896
- args: [],
897
- func: '<?>.wasm-function[42]',
898
- url: '[wasm code]',
899
- column: undefined,
900
- line: undefined,
901
- })
902
- })
903
-
904
- it('should parse Safari Wasm stack frames from file URL', () => {
905
- const wasmStack = `
906
- RuntimeError: Some Wasm Error
907
- myModule.wasm-function[crashFunc]@[wasm code]
908
- regularJsFunc@http://example.com/script.js:10:5
909
- `
910
- const mockErr = { message: 'Some Wasm Error', name: 'RuntimeError', stack: wasmStack }
911
- const stackFrames = computeStackTrace(mockErr)
912
-
913
- expect(stackFrames.stack.length).toBe(2)
914
- expect(stackFrames.stack[0]).toEqual({
915
- args: [],
916
- func: 'myModule.wasm-function[crashFunc]',
917
- url: '[wasm code]',
918
- line: undefined,
919
- column: undefined,
920
- })
921
- })
922
-
923
- it('should parse Chrome WebAssembly stack frames', () => {
924
- const wasmStack = `
925
- Error: Wasm Error
926
- at myModule.foo (http://example.com/myModule.wasm:wasm-function[42]:0x1a3b)
927
- at bar (http://example.com/script.js:10:5)
928
- `
929
- const mockErr = { message: 'Wasm Error', name: 'Error', stack: wasmStack }
930
- const stackFrames = computeStackTrace(mockErr)
931
-
932
- expect(stackFrames.stack.length).toBe(2)
933
- expect(stackFrames.stack[0]).toEqual({
934
- args: [],
935
- func: 'myModule.foo',
936
- url: 'http://example.com/myModule.wasm:wasm-function[42]:0x1a3b',
937
- line: undefined,
938
- column: undefined,
939
- })
940
- })
941
-
942
- it('should parse Firefox WebAssembly stack frames', () => {
943
- const wasmStack = `
944
- Error: Wasm Error
945
- myModule.foo@http://example.com/my-module.wasm:wasm-function[42]:0x1a3b
946
- bar@http://example.com/script.js:10:5
947
- `
948
- const mockErr = { message: 'Wasm Error', name: 'Error', stack: wasmStack }
949
- const stackFrames = computeStackTrace(mockErr)
950
-
951
- expect(stackFrames.stack.length).toBe(2)
952
-
953
- expect(stackFrames.stack[0]).toEqual({
954
- args: [],
955
- func: 'myModule.foo',
956
- url: 'http://example.com/my-module.wasm:wasm-function[42]:0x1a3b',
957
- line: undefined,
958
- column: undefined,
959
- })
960
- })
961
-
962
- it('should normalize non native errors stacktraces across browsers', () => {
963
- class DatadogTestCustomError extends Error {
964
- constructor() {
965
- super()
966
- this.name = 'Error' // set name to Error so that no browser would default to the constructor name
967
- }
968
- }
969
- class DatadogTestCustomError2 extends DatadogTestCustomError {}
970
-
971
- const [customError, customErrorWithInheritance, customErrorWithAnonymousInheritance, nativeError] = [
972
- DatadogTestCustomError,
973
- DatadogTestCustomError2,
974
- // this is an anonymous class, which has no name
975
- // we're checking if the stacktrace is correctly reported for this specific case (with the class name missing)
976
- class extends DatadogTestCustomError2 {
977
- constructor() {
978
- super()
979
- this.name = 'Error'
980
- }
981
- },
982
- Error,
983
- ].map((errConstructor) => new errConstructor()) // so that both errors should exactly have the same stacktrace
984
-
985
- expect(computeStackTrace(customError.stack)).toEqual(computeStackTrace(nativeError.stack))
986
- expect(computeStackTrace(customErrorWithInheritance.stack)).toEqual(computeStackTrace(nativeError.stack))
987
- expect(computeStackTrace(customErrorWithAnonymousInheritance.stack)).toEqual(computeStackTrace(nativeError.stack))
988
- })
989
-
990
- it('should skip empty lines in stacktraces', () => {
991
- const wasmStack = `
992
- Error: Wasm Error
993
- myModule.foo@http://example.com/my-module.wasm:wasm-function[42]:0x1a3b\n \n\t\n`
994
- const mockErr = { message: 'Wasm Error', name: 'Error', stack: wasmStack }
995
- const stackFrames = computeStackTrace(mockErr)
996
-
997
- expect(stackFrames.stack.length).toBe(1)
998
-
999
- expect(stackFrames.stack[0]).toEqual({
1000
- args: [],
1001
- func: 'myModule.foo',
1002
- url: 'http://example.com/my-module.wasm:wasm-function[42]:0x1a3b',
1003
- line: undefined,
1004
- column: undefined,
1005
- })
1006
- })
1007
- })