diff --git a/eslint-local-rules/disallowSideEffects.js b/eslint-local-rules/disallowSideEffects.js index 68ea77279d..21f403a75a 100644 --- a/eslint-local-rules/disallowSideEffects.js +++ b/eslint-local-rules/disallowSideEffects.js @@ -195,10 +195,12 @@ function isAllowedCallExpression({ callee }) { */ /* eslint-enable max-len */ function isAllowedNewExpression({ callee }) { - // Allow "new WeakMap()" - if (callee.name === 'WeakMap') { - return true - } + switch (callee.name) { + case 'WeakMap': // Allow "new WeakMap()" + case 'RegExp': // Allow "new RegExp()" + return true - return false + default: + return false + } } diff --git a/packages/core/src/domain/tracekit/computeStackTrace.spec.ts b/packages/core/src/domain/tracekit/computeStackTrace.spec.ts index 762d827c2f..dcc592416a 100644 --- a/packages/core/src/domain/tracekit/computeStackTrace.spec.ts +++ b/packages/core/src/domain/tracekit/computeStackTrace.spec.ts @@ -468,6 +468,60 @@ Error: foo }) }) + it('should parse Chrome error that only contain file name, with no path prefix', () => { + const stack = `Error: RTE Simulation + at foo$bar$oof$rab (events.cljs:1060:12) + at func1$func2$func3$func4 (std_interceptors.js:128:19) + at eval (std_interceptors.jsx:132:29)` + + const stackFrames = computeStackTrace({ stack } as Error) + expect(stackFrames.stack.length).toEqual(3) + expect(stackFrames.stack[0]).toEqual({ + args: [], + column: 12, + func: 'foo$bar$oof$rab', + line: 1060, + url: 'events.cljs', + }) + expect(stackFrames.stack[1]).toEqual({ + args: [], + column: 19, + func: 'func1$func2$func3$func4', + line: 128, + url: 'std_interceptors.js', + }) + expect(stackFrames.stack[2]).toEqual({ + args: [], + column: 29, + func: 'eval', + line: 132, + url: 'std_interceptors.jsx', + }) + }) + + it('should parse Chrome anonymous function errors', () => { + const stack = `Error: RTE Simulation + at https://datadoghq.com/somefile.js:8489:191 + at chrome-extension:///content/index.js:85:37379` + + const stackFrames = computeStackTrace({ stack } as Error) + expect(stackFrames.stack.length).toEqual(2) + expect(stackFrames.stack[0]).toEqual({ + args: [], + column: 191, + func: '?', + line: 8489, + url: 'https://datadoghq.com/somefile.js', + }) + expect(stackFrames.stack[1]).toEqual({ + args: [], + column: 37379, + func: '?', + line: 85, + url: 'chrome-extension:///content/index.js', + }) + }) + it('should parse Chrome 15 error', () => { const stackFrames = computeStackTrace(CapturedExceptions.CHROME_15 as any) diff --git a/packages/core/src/domain/tracekit/computeStackTrace.ts b/packages/core/src/domain/tracekit/computeStackTrace.ts index 79f6be3edb..1e6db364c6 100644 --- a/packages/core/src/domain/tracekit/computeStackTrace.ts +++ b/packages/core/src/domain/tracekit/computeStackTrace.ts @@ -11,7 +11,8 @@ export function computeStackTrace(ex: unknown): StackTrace { const stackProperty = tryToGetString(ex, 'stack') if (stackProperty) { stackProperty.split('\n').forEach((line) => { - const stackFrame = parseChromeLine(line) || parseWinLine(line) || parseGeckoLine(line) + const stackFrame = + parseChromeLine(line) || parseChromeAnonymousLine(line) || parseWinLine(line) || parseGeckoLine(line) if (stackFrame) { if (!stackFrame.func && stackFrame.line) { stackFrame.func = UNKNOWN_FUNCTION @@ -28,11 +29,11 @@ export function computeStackTrace(ex: unknown): StackTrace { stack, } } +const fileUrl = '((?:file|https?|blob|chrome-extension|native|eval|webpack||\\w+\\.|\\/).*?)' +const filePosition = '(?::(\\d+))' +const CHROME_LINE_RE = new RegExp(`^\\s*at (.*?) ?\\(${fileUrl}${filePosition}?${filePosition}?\\)?\\s*$`, 'i') -const CHROME_LINE_RE = - // eslint-disable-next-line max-len - /^\s*at (.*?) ?\(((?:file|https?|blob|chrome-extension|native|eval|webpack||\/).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i -const CHROME_EVAL_RE = /\((\S*)(?::(\d+))(?::(\d+))\)/ +const CHROME_EVAL_RE = new RegExp(`\\((\\S*)${filePosition}${filePosition}\\)`) function parseChromeLine(line: string): StackFrame | undefined { const parts = CHROME_LINE_RE.exec(line) @@ -61,6 +62,24 @@ function parseChromeLine(line: string): StackFrame | undefined { } } +const CHROME_ANONYMOUS_FUNCTION_RE = new RegExp(`^\\s*at ?${fileUrl}${filePosition}?${filePosition}??\\s*$`, 'i') + +function parseChromeAnonymousLine(line: string): StackFrame | undefined { + const parts = CHROME_ANONYMOUS_FUNCTION_RE.exec(line) + + if (!parts) { + return + } + + return { + args: [], + column: parts[3] ? +parts[3] : undefined, + func: UNKNOWN_FUNCTION, + line: parts[2] ? +parts[2] : undefined, + url: parts[1], + } +} + const WINJS_LINE_RE = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:file|ms-appx|https?|webpack|blob):.*?):(\d+)(?::(\d+))?\)?\s*$/i