@samitouri / QOS-React-2 / commits / b9fc3d8d59

DevTools temporarily disable prepareStackTrace before creating custom component stacks (#18717)

Brian Vaughn committed Apr 23, 2020 at 09:02 UTC b9fc3d8d59b0de5e4cec1619a3645494af169bae
2 files changed +54
packages/react-devtools-shared/src/__tests__/console-test.js
+47
@@ -346,4 +346,51 @@ describe('console', () => {
346 '\n in Child (at **)',
347 );
348 });
349 +
350 + it('should be resilient to prepareStackTrace', () => {
351 + Error.prepareStackTrace = function(error, callsites) {
352 + const stack = ['An error occurred:', error.message];
353 + for (let i = 0; i < callsites.length; i++) {
354 + const callsite = callsites[i];
355 + stack.push(
356 + '\t' + callsite.getFunctionName(),
357 + '\t\tat ' + callsite.getFileName(),
358 + '\t\ton line ' + callsite.getLineNumber(),
359 + );
360 + }
361 +
362 + return stack.join('\n');
363 + };
364 +
365 + const Intermediate = ({children}) => children;
366 + const Parent = ({children}) => (
367 + <Intermediate>
368 + <Child />
369 + </Intermediate>
370 + );
371 + const Child = ({children}) => {
372 + fakeConsole.error('error');
373 + fakeConsole.log('log');
374 + fakeConsole.warn('warn');
375 + return null;
376 + };
377 +
378 + act(() => ReactDOM.render(<Parent />, document.createElement('div')));
379 +
380 + expect(mockLog).toHaveBeenCalledTimes(1);
381 + expect(mockLog.mock.calls[0]).toHaveLength(1);
382 + expect(mockLog.mock.calls[0][0]).toBe('log');
383 + expect(mockWarn).toHaveBeenCalledTimes(1);
384 + expect(mockWarn.mock.calls[0]).toHaveLength(2);
385 + expect(mockWarn.mock.calls[0][0]).toBe('warn');
386 + expect(normalizeCodeLocInfo(mockWarn.mock.calls[0][1])).toEqual(
387 + '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)',
388 + );
389 + expect(mockError).toHaveBeenCalledTimes(1);
390 + expect(mockError.mock.calls[0]).toHaveLength(2);
391 + expect(mockError.mock.calls[0][0]).toBe('error');
392 + expect(normalizeCodeLocInfo(mockError.mock.calls[0][1])).toBe(
393 + '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)',
394 + );
395 + });
396 });
packages/react-devtools-shared/src/backend/DevToolsComponentStackFrame.js
+7
@@ -80,6 +80,10 @@ export function describeNativeComponentFrame(
80
81 let control;
82
83 + const previousPrepareStackTrace = Error.prepareStackTrace;
84 + // $FlowFixMe It does accept undefined.
85 + Error.prepareStackTrace = undefined;
86 +
87 reentry = true;
88 let previousDispatcher;
89 if (__DEV__) {
@@ -181,6 +185,9 @@ export function describeNativeComponentFrame(
185 }
186 } finally {
187 reentry = false;
188 +
189 + Error.prepareStackTrace = previousPrepareStackTrace;
190 +
191 if (__DEV__) {
192 currentDispatcherRef.current = previousDispatcher;
193 reenableLogs();