@@ -80,9 +80,25 @@ export function registerRenderer(renderer: ReactRenderer): void {
8080 }
8181}
8282
83+ const consoleSettingsRef = {
84+ appendComponentStack : false ,
85+ breakOnConsoleErrors : false ,
86+ } ;
87+
8388// Patches whitelisted console methods to append component stack for the current fiber.
8489// Call unpatch() to remove the injected behavior.
85- export function patch ( ) : void {
90+ export function patch ( {
91+ appendComponentStack,
92+ breakOnConsoleErrors,
93+ } : {
94+ appendComponentStack : boolean ,
95+ breakOnConsoleErrors : boolean ,
96+ } ) : void {
97+ // Settings may change after we've patched the console.
98+ // Using a shared ref allows the patch function to read the latest values.
99+ consoleSettingsRef . appendComponentStack = appendComponentStack ;
100+ consoleSettingsRef . breakOnConsoleErrors = breakOnConsoleErrors ;
101+
86102 if ( unpatchFn !== null ) {
87103 // Don't patch twice.
88104 return ;
@@ -105,40 +121,56 @@ export function patch(): void {
105121 targetConsole [ method ] ) ;
106122
107123 const overrideMethod = ( ...args ) => {
108- try {
109- // If we are ever called with a string that already has a component stack, e.g. a React error/warning,
110- // don't append a second stack.
111- const lastArg = args . length > 0 ? args [ args . length - 1 ] : null ;
112- const alreadyHasComponentStack =
113- lastArg !== null &&
114- ( PREFIX_REGEX . test ( lastArg ) ||
115- ROW_COLUMN_NUMBER_REGEX . test ( lastArg ) ) ;
116-
117- if ( ! alreadyHasComponentStack ) {
118- // If there's a component stack for at least one of the injected renderers, append it.
119- // We don't handle the edge case of stacks for more than one (e.g. interleaved renderers?)
120- // eslint-disable-next-line no-for-of-loops/no-for-of-loops
121- for ( const {
122- currentDispatcherRef,
123- getCurrentFiber,
124- workTagMap,
125- } of injectedRenderers . values ( ) ) {
126- const current : ?Fiber = getCurrentFiber ( ) ;
127- if ( current != null ) {
128- const componentStack = getStackByFiberInDevAndProd (
129- workTagMap ,
130- current ,
131- currentDispatcherRef ,
132- ) ;
133- if ( componentStack !== '' ) {
134- args . push ( componentStack ) ;
124+ const latestAppendComponentStack =
125+ consoleSettingsRef . appendComponentStack ;
126+ const latestBreakOnConsoleErrors =
127+ consoleSettingsRef . breakOnConsoleErrors ;
128+
129+ if ( latestAppendComponentStack ) {
130+ try {
131+ // If we are ever called with a string that already has a component stack, e.g. a React error/warning,
132+ // don't append a second stack.
133+ const lastArg = args . length > 0 ? args [ args . length - 1 ] : null ;
134+ const alreadyHasComponentStack =
135+ lastArg !== null &&
136+ ( PREFIX_REGEX . test ( lastArg ) ||
137+ ROW_COLUMN_NUMBER_REGEX . test ( lastArg ) ) ;
138+
139+ if ( ! alreadyHasComponentStack ) {
140+ // If there's a component stack for at least one of the injected renderers, append it.
141+ // We don't handle the edge case of stacks for more than one (e.g. interleaved renderers?)
142+ // eslint-disable-next-line no-for-of-loops/no-for-of-loops
143+ for ( const {
144+ currentDispatcherRef,
145+ getCurrentFiber,
146+ workTagMap,
147+ } of injectedRenderers . values ( ) ) {
148+ const current : ?Fiber = getCurrentFiber ( ) ;
149+ if ( current != null ) {
150+ const componentStack = getStackByFiberInDevAndProd (
151+ workTagMap ,
152+ current ,
153+ currentDispatcherRef ,
154+ ) ;
155+ if ( componentStack !== '' ) {
156+ args . push ( componentStack ) ;
157+ }
158+ break ;
135159 }
136- break ;
137160 }
138161 }
162+ } catch ( error ) {
163+ // Don't let a DevTools or React internal error interfere with logging.
139164 }
140- } catch ( error ) {
141- // Don't let a DevTools or React internal error interfere with logging.
165+ }
166+
167+ if ( latestBreakOnConsoleErrors ) {
168+ // --- Welcome to debugging with React DevTools ---
169+ // This debugger statement means that you've enabled the "break on warnings" feature.
170+ // Use the browser's Call Stack panel to step out of this override function-
171+ // to where the original warning or error was logged.
172+ // eslint-disable-next-line no-debugger
173+ debugger ;
142174 }
143175
144176 originalMethod ( ...args ) ;
0 commit comments