From dbdfa836294d343f7445890c3e931497e56ccd99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Og=C3=B3rek?= Date: Wed, 14 Aug 2019 12:43:36 +0200 Subject: [PATCH] feat: Use framesToPop for InvaliantViolations in React errors --- CHANGELOG.md | 4 ++ packages/browser/src/tracekit.ts | 24 +++++++-- .../browser/test/unit/tracekit/custom.test.ts | 53 +++++++++++++++++++ 3 files changed, 77 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1900331bd4c6..5977af66b9b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## Unreleased + +- [browser] feat: Use framesToPop for InvaliantViolations in React errors (#2204) + ## 5.6.1 - [core] fix: Correctly detect when client is enabled before installing integrations (#2193) diff --git a/packages/browser/src/tracekit.ts b/packages/browser/src/tracekit.ts index 55668ec55e37..9cfbf07a3c7f 100644 --- a/packages/browser/src/tracekit.ts +++ b/packages/browser/src/tracekit.ts @@ -870,6 +870,7 @@ TraceKit._computeStackTrace = (function _computeStackTraceWrapper() { */ function computeStackTrace(ex: any, depth: any) { var stack = null; + var popSize = ex && ex.framesToPop; depth = depth == null ? 0 : +depth; try { @@ -878,28 +879,28 @@ TraceKit._computeStackTrace = (function _computeStackTraceWrapper() { // property first!! stack = _computeStackTraceFromStacktraceProp(ex); if (stack) { - return stack; + return popFrames(stack, popSize); } } catch (e) {} try { stack = _computeStackTraceFromStackProp(ex); if (stack) { - return stack; + return popFrames(stack, popSize); } } catch (e) {} try { stack = _computeStackTraceFromOperaMultiLineMessage(ex); if (stack) { - return stack; + return popFrames(stack, popSize); } } catch (e) {} try { stack = _computeStackTraceByWalkingCallerChain(ex, depth + 1); if (stack) { - return stack; + return popFrames(stack, popSize); } } catch (e) {} @@ -911,6 +912,21 @@ TraceKit._computeStackTrace = (function _computeStackTraceWrapper() { }; } + function popFrames(stacktrace: any, popSize: number): any { + if (Number.isNaN(popSize)) { + return stacktrace; + } + + try { + return { + ...stacktrace, + stack: stacktrace.stack.slice(popSize), + }; + } catch (e) { + return stacktrace; + } + } + (computeStackTrace as any)._augmentStackTraceWithInitialElement = _augmentStackTraceWithInitialElement; (computeStackTrace as any)._computeStackTraceFromStackProp = _computeStackTraceFromStackProp; diff --git a/packages/browser/test/unit/tracekit/custom.test.ts b/packages/browser/test/unit/tracekit/custom.test.ts index fe715d240788..a41760cf794c 100644 --- a/packages/browser/test/unit/tracekit/custom.test.ts +++ b/packages/browser/test/unit/tracekit/custom.test.ts @@ -284,4 +284,57 @@ describe('Tracekit - Custom Tests', () => { ]); }); }); + + describe('React', () => { + it('should correctly parse Invariant Violation errors and use framesToPop to drop info message', () => { + const REACT_INVARIANT_VIOLATION_EXCEPTION = { + framesToPop: 1, + message: + 'Minified React error #31; visit https://reactjs.org/docs/error-decoder.html?invariant=31&args[]=object%20with%20keys%20%7B%7D&args[]= for the full message or use the non-minified dev environment for full errors and additional helpful warnings. ', + name: 'Invariant Violation', + stack: `Invariant Violation: Minified React error #31; visit https://reactjs.org/docs/error-decoder.html?invariant=31&args[]=object%20with%20keys%20%7B%7D&args[]= for the full message or use the non-minified dev environment for full errors and additional helpful warnings. + at http://localhost:5000/static/js/foo.chunk.js:1:21738 + at a (http://localhost:5000/static/js/foo.chunk.js:1:21841) + at ho (http://localhost:5000/static/js/foo.chunk.js:1:68735) + at f (http://localhost:5000/:1:980)`, + }; + + const stacktrace = _computeStackTrace(REACT_INVARIANT_VIOLATION_EXCEPTION); + + expect(stacktrace.stack).deep.equal([ + { + args: [], + column: 21738, + context: null, + func: '?', + line: 1, + url: 'http://localhost:5000/static/js/foo.chunk.js', + }, + { + args: [], + column: 21841, + context: null, + func: 'a', + line: 1, + url: 'http://localhost:5000/static/js/foo.chunk.js', + }, + { + args: [], + column: 68735, + context: null, + func: 'ho', + line: 1, + url: 'http://localhost:5000/static/js/foo.chunk.js', + }, + { + args: [], + column: 980, + context: null, + func: 'f', + line: 1, + url: 'http://localhost:5000/', + }, + ]); + }); + }); });