Skip to content

Commit 615ec19

Browse files
lunaruanzhengjitf
authored andcommitted
[DevTools] Throw error in console without interfering with logs (facebook#22175)
1 parent 312278f commit 615ec19

File tree

2 files changed

+103
-12
lines changed

2 files changed

+103
-12
lines changed

packages/react-devtools-shared/src/__tests__/console-test.js

Lines changed: 100 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,19 @@
66
*
77
* @flow
88
*/
9+
let React;
10+
let ReactDOM;
11+
let act;
12+
let fakeConsole;
13+
let legacyRender;
14+
let mockError;
15+
let mockInfo;
16+
let mockLog;
17+
let mockWarn;
18+
let patchConsole;
19+
let unpatchConsole;
920

1021
describe('console', () => {
11-
let React;
12-
let ReactDOM;
13-
let act;
14-
let fakeConsole;
15-
let legacyRender;
16-
let mockError;
17-
let mockInfo;
18-
let mockLog;
19-
let mockWarn;
20-
let patchConsole;
21-
let unpatchConsole;
22-
2322
beforeEach(() => {
2423
jest.resetModules();
2524

@@ -553,3 +552,92 @@ describe('console', () => {
553552
expect(mockError.mock.calls[0][0]).toBe('error');
554553
});
555554
});
555+
556+
describe('console error', () => {
557+
beforeEach(() => {
558+
jest.resetModules();
559+
560+
const Console = require('react-devtools-shared/src/backend/console');
561+
patchConsole = Console.patch;
562+
unpatchConsole = Console.unpatch;
563+
564+
// Patch a fake console so we can verify with tests below.
565+
// Patching the real console is too complicated,
566+
// because Jest itself has hooks into it as does our test env setup.
567+
mockError = jest.fn();
568+
mockInfo = jest.fn();
569+
mockLog = jest.fn();
570+
mockWarn = jest.fn();
571+
fakeConsole = {
572+
error: mockError,
573+
info: mockInfo,
574+
log: mockLog,
575+
warn: mockWarn,
576+
};
577+
578+
Console.dangerous_setTargetConsoleForTesting(fakeConsole);
579+
580+
// Note the Console module only patches once,
581+
// so it's important to patch the test console before injection.
582+
patchConsole({
583+
appendComponentStack: true,
584+
breakOnWarn: false,
585+
showInlineWarningsAndErrors: false,
586+
hideDoubleLogsInStrictLegacy: false,
587+
});
588+
589+
const inject = global.__REACT_DEVTOOLS_GLOBAL_HOOK__.inject;
590+
global.__REACT_DEVTOOLS_GLOBAL_HOOK__.inject = internals => {
591+
internals.getIsStrictMode = () => {
592+
throw Error('foo');
593+
};
594+
inject(internals);
595+
596+
Console.registerRenderer(internals);
597+
};
598+
599+
React = require('react');
600+
ReactDOM = require('react-dom');
601+
602+
const utils = require('./utils');
603+
act = utils.act;
604+
legacyRender = utils.legacyRender;
605+
});
606+
607+
it('error in console log throws without interfering with logging', () => {
608+
const container = document.createElement('div');
609+
const root = ReactDOM.createRoot(container);
610+
611+
function App() {
612+
fakeConsole.log('log');
613+
fakeConsole.warn('warn');
614+
fakeConsole.error('error');
615+
return <div />;
616+
}
617+
618+
patchConsole({
619+
appendComponentStack: true,
620+
breakOnWarn: false,
621+
showInlineWarningsAndErrors: false,
622+
hideConsoleLogsInStrictMode: false,
623+
});
624+
625+
expect(() => {
626+
act(() => {
627+
root.render(<App />);
628+
});
629+
}).toThrowError('foo');
630+
631+
expect(mockLog).toHaveBeenCalledTimes(1);
632+
expect(mockLog.mock.calls[0]).toHaveLength(1);
633+
expect(mockLog.mock.calls[0][0]).toBe('log');
634+
635+
expect(mockWarn).toHaveBeenCalledTimes(1);
636+
expect(mockWarn.mock.calls[0]).toHaveLength(1);
637+
expect(mockWarn.mock.calls[0][0]).toBe('warn');
638+
639+
expect(mockError).toHaveBeenCalledTimes(1);
640+
expect(mockError.mock.calls[0]).toHaveLength(1);
641+
expect(mockError.mock.calls[0][0]).toBe('error');
642+
});
643+
});

packages/react-devtools-shared/src/backend/console.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,9 @@ export function patch({
222222
}
223223
} catch (error) {
224224
// Don't let a DevTools or React internal error interfere with logging.
225+
setTimeout(() => {
226+
throw error;
227+
}, 0);
225228
} finally {
226229
break;
227230
}

0 commit comments

Comments
 (0)