diff --git a/packages/react-devtools-shared/src/__tests__/console-test.js b/packages/react-devtools-shared/src/__tests__/console-test.js
index 74e9fed9ff..710499ce39 100644
--- a/packages/react-devtools-shared/src/__tests__/console-test.js
+++ b/packages/react-devtools-shared/src/__tests__/console-test.js
@@ -346,4 +346,51 @@ describe('console', () => {
'\n in Child (at **)',
);
});
+
+ it('should be resilient to prepareStackTrace', () => {
+ Error.prepareStackTrace = function(error, callsites) {
+ const stack = ['An error occurred:', error.message];
+ for (let i = 0; i < callsites.length; i++) {
+ const callsite = callsites[i];
+ stack.push(
+ '\t' + callsite.getFunctionName(),
+ '\t\tat ' + callsite.getFileName(),
+ '\t\ton line ' + callsite.getLineNumber(),
+ );
+ }
+
+ return stack.join('\n');
+ };
+
+ const Intermediate = ({children}) => children;
+ const Parent = ({children}) => (
+
+
+
+ );
+ const Child = ({children}) => {
+ fakeConsole.error('error');
+ fakeConsole.log('log');
+ fakeConsole.warn('warn');
+ return null;
+ };
+
+ act(() => ReactDOM.render(, document.createElement('div')));
+
+ expect(mockLog).toHaveBeenCalledTimes(1);
+ expect(mockLog.mock.calls[0]).toHaveLength(1);
+ expect(mockLog.mock.calls[0][0]).toBe('log');
+ expect(mockWarn).toHaveBeenCalledTimes(1);
+ expect(mockWarn.mock.calls[0]).toHaveLength(2);
+ expect(mockWarn.mock.calls[0][0]).toBe('warn');
+ expect(normalizeCodeLocInfo(mockWarn.mock.calls[0][1])).toEqual(
+ '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)',
+ );
+ expect(mockError).toHaveBeenCalledTimes(1);
+ expect(mockError.mock.calls[0]).toHaveLength(2);
+ expect(mockError.mock.calls[0][0]).toBe('error');
+ expect(normalizeCodeLocInfo(mockError.mock.calls[0][1])).toBe(
+ '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)',
+ );
+ });
});
diff --git a/packages/react-devtools-shared/src/backend/DevToolsComponentStackFrame.js b/packages/react-devtools-shared/src/backend/DevToolsComponentStackFrame.js
index f4aab13ece..b3b306a111 100644
--- a/packages/react-devtools-shared/src/backend/DevToolsComponentStackFrame.js
+++ b/packages/react-devtools-shared/src/backend/DevToolsComponentStackFrame.js
@@ -80,6 +80,10 @@ export function describeNativeComponentFrame(
let control;
+ const previousPrepareStackTrace = Error.prepareStackTrace;
+ // $FlowFixMe It does accept undefined.
+ Error.prepareStackTrace = undefined;
+
reentry = true;
let previousDispatcher;
if (__DEV__) {
@@ -181,6 +185,9 @@ export function describeNativeComponentFrame(
}
} finally {
reentry = false;
+
+ Error.prepareStackTrace = previousPrepareStackTrace;
+
if (__DEV__) {
currentDispatcherRef.current = previousDispatcher;
reenableLogs();