Skip to content

Commit 642a678

Browse files
authored
Replace ReactFiberErrorLogger injection with static forks (#11717)
1 parent 060581b commit 642a678

File tree

10 files changed

+71
-62
lines changed

10 files changed

+71
-62
lines changed

packages/react-dom/src/client/ReactDOMFB.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99

1010
import * as ReactFiberTreeReflection from 'react-reconciler/reflection';
1111
import * as ReactInstanceMap from 'shared/ReactInstanceMap';
12-
// TODO: direct imports like some-package/src/* are bad. Fix me.
13-
import * as ReactFiberErrorLogger from 'react-reconciler/src/ReactFiberErrorLogger';
1412
import ReactErrorUtils from 'shared/ReactErrorUtils';
1513
import {addUserTimingListener} from 'shared/ReactFeatureFlags';
1614

@@ -25,7 +23,6 @@ Object.assign(
2523
// These are real internal dependencies that are trickier to remove:
2624
ReactBrowserEventEmitter,
2725
ReactErrorUtils,
28-
ReactFiberErrorLogger,
2926
ReactFiberTreeReflection,
3027
ReactDOMComponentTree,
3128
ReactInstanceMap,

packages/react-native-renderer/src/ReactNativeRenderer.js

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ import type {ReactNodeList} from 'shared/ReactTypes';
1212

1313
import './ReactNativeInjection';
1414

15-
// TODO: direct imports like some-package/src/* are bad. Fix me.
16-
import * as ReactFiberErrorLogger from 'react-reconciler/src/ReactFiberErrorLogger';
1715
import * as ReactPortal from 'react-reconciler/src/ReactPortal';
1816
import * as ReactGenericBatching from 'events/ReactGenericBatching';
1917
import TouchHistoryMath from 'events/TouchHistoryMath';
@@ -22,7 +20,6 @@ import ReactVersion from 'shared/ReactVersion';
2220
// Module provided by RN:
2321
import UIManager from 'UIManager';
2422

25-
import {showDialog} from './ReactNativeFiberErrorDialog';
2623
import NativeMethodsMixin from './NativeMethodsMixin';
2724
import ReactNativeBridgeEventPlugin from './ReactNativeBridgeEventPlugin';
2825
import ReactNativeComponent from './ReactNativeComponent';
@@ -40,10 +37,6 @@ ReactGenericBatching.injection.injectFiberBatchedUpdates(
4037

4138
const roots = new Map();
4239

43-
// Intercept lifecycle errors and ensure they are shown with the correct stack
44-
// trace within the native redbox component.
45-
ReactFiberErrorLogger.injection.injectDialog(showDialog);
46-
4740
const ReactNativeRenderer: ReactNativeType = {
4841
NativeComponent: ReactNativeComponent,
4942

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/**
2+
* Copyright (c) 2013-present, Facebook, Inc.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow
8+
*/
9+
10+
import type {CapturedError} from './ReactFiberScheduler';
11+
12+
// This module is forked in different environments.
13+
// By default, return `true` to log errors to the console.
14+
// Forks can return `false` if this isn't desirable.
15+
export function showErrorDialog(capturedError: CapturedError): boolean {
16+
return true;
17+
}

packages/react-reconciler/src/ReactFiberErrorLogger.js

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,12 @@
99

1010
import type {CapturedError} from './ReactFiberScheduler';
1111

12-
import invariant from 'fbjs/lib/invariant';
13-
14-
const defaultShowDialog = (capturedError: CapturedError) => true;
15-
16-
let showDialog = defaultShowDialog;
12+
import {showErrorDialog} from './ReactFiberErrorDialog';
1713

1814
export function logCapturedError(capturedError: CapturedError): void {
19-
const logError = showDialog(capturedError);
15+
const logError = showErrorDialog(capturedError);
2016

21-
// Allow injected showDialog() to prevent default console.error logging.
17+
// Allow injected showErrorDialog() to prevent default console.error logging.
2218
// This enables renderers like ReactNative to better manage redbox behavior.
2319
if (logError === false) {
2420
return;
@@ -78,21 +74,3 @@ export function logCapturedError(capturedError: CapturedError): void {
7874
console.error(error);
7975
}
8076
}
81-
82-
export const injection = {
83-
/**
84-
* Display custom dialog for lifecycle errors.
85-
* Return false to prevent default behavior of logging to console.error.
86-
*/
87-
injectDialog(fn: (e: CapturedError) => boolean) {
88-
invariant(
89-
showDialog === defaultShowDialog,
90-
'The custom dialog was already injected.',
91-
);
92-
invariant(
93-
typeof fn === 'function',
94-
'Injected showDialog() must be a function.',
95-
);
96-
showDialog = fn;
97-
},
98-
};

packages/react-native-renderer/src/ReactNativeFiberErrorDialog.js renamed to packages/react-reconciler/src/forks/ReactFiberErrorDialog.native.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @flow
88
*/
99

10-
import type {CapturedError} from 'react-reconciler/src/ReactFiberScheduler';
10+
import type {CapturedError} from '../ReactFiberScheduler';
1111

1212
// Module provided by RN:
1313
import ExceptionsManager from 'ExceptionsManager';
@@ -16,7 +16,7 @@ import ExceptionsManager from 'ExceptionsManager';
1616
* Intercept lifecycle errors and ensure they are shown with the correct stack
1717
* trace within the native redbox component.
1818
*/
19-
export function showDialog(capturedError: CapturedError): boolean {
19+
export function showErrorDialog(capturedError: CapturedError): boolean {
2020
const {componentStack, error} = capturedError;
2121

2222
let errorToHandle: Error;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/**
2+
* Copyright (c) 2013-present, Facebook, Inc.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow
8+
*/
9+
10+
import type {CapturedError} from '../ReactFiberScheduler';
11+
12+
// Provided by www
13+
const ReactFiberErrorDialogWWW = require('ReactFiberErrorDialog');
14+
15+
export function showErrorDialog(capturedError: CapturedError): boolean {
16+
return ReactFiberErrorDialogWWW.showErrorDialog(capturedError);
17+
}

packages/react-rt-renderer/src/ReactNativeRT.js

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,6 @@ import type {ReactNodeList} from 'shared/ReactTypes';
1919
import 'InitializeCore';
2020
import './ReactNativeRTEventEmitter';
2121

22-
// TODO: direct imports like some-package/src/* are bad. Fix me.
23-
import * as ReactFiberErrorLogger from 'react-reconciler/src/ReactFiberErrorLogger';
24-
import {showDialog} from 'react-native-renderer/src/ReactNativeFiberErrorDialog';
2522
import * as ReactPortal from 'react-reconciler/src/ReactPortal';
2623
import * as ReactGenericBatching from 'events/ReactGenericBatching';
2724
import ReactVersion from 'shared/ReactVersion';
@@ -36,10 +33,6 @@ ReactGenericBatching.injection.injectFiberBatchedUpdates(
3633

3734
const roots = new Map();
3835

39-
// Intercept lifecycle errors and ensure they are shown with the correct stack
40-
// trace within the native redbox component.
41-
ReactFiberErrorLogger.injection.injectDialog(showDialog);
42-
4336
const ReactNativeRTFiber: ReactNativeRTType = {
4437
render(element: React$Element<any>, containerTag: any, callback: ?Function) {
4538
let root = roots.get(containerTag);

scripts/flow/environment.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,14 @@ declare var __REACT_DEVTOOLS_GLOBAL_HOOK__: any; /*?{
1313
inject: ?((stuff: Object) => void)
1414
};*/
1515

16-
// ReactFeatureFlags rollup shim for www imports the www implementation.
16+
// ReactFeatureFlags www fork
1717
declare module 'ReactFeatureFlags' {
1818
declare module.exports: any;
1919
}
20+
21+
// ReactFiberErrorDialog www fork
22+
declare module 'ReactFiberErrorDialog' {
23+
declare module.exports: {
24+
showErrorDialog: (error: mixed) => boolean,
25+
};
26+
}

scripts/rollup/forks.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ const UMD_DEV = bundleTypes.UMD_DEV;
66
const UMD_PROD = bundleTypes.UMD_PROD;
77
const FB_DEV = bundleTypes.FB_DEV;
88
const FB_PROD = bundleTypes.FB_PROD;
9+
const RN_DEV = bundleTypes.RN_DEV;
10+
const RN_PROD = bundleTypes.RN_PROD;
911

1012
// If you need to replace a file with another file for a specific environment,
1113
// add it to this list with the logic for choosing the right replacement.
@@ -66,6 +68,28 @@ const forks = Object.freeze({
6668
return null;
6769
}
6870
},
71+
72+
// Different behavior for caught errors.
73+
'react-reconciler/src/ReactFiberErrorDialog': (bundleType, entry) => {
74+
switch (bundleType) {
75+
case FB_DEV:
76+
case FB_PROD:
77+
// Use the www fork which shows an error dialog.
78+
return 'react-reconciler/src/forks/ReactFiberErrorDialog.www.js';
79+
case RN_DEV:
80+
case RN_PROD:
81+
switch (entry) {
82+
case 'react-native-renderer':
83+
case 'react-rt-renderer':
84+
// Use the RN fork which plays well with redbox.
85+
return 'react-reconciler/src/forks/ReactFiberErrorDialog.native.js';
86+
default:
87+
return null;
88+
}
89+
default:
90+
return null;
91+
}
92+
},
6993
});
7094

7195
module.exports = forks;

scripts/rollup/shims/facebook-www/ReactFiberErrorLogger.js

Lines changed: 0 additions & 17 deletions
This file was deleted.

0 commit comments

Comments
 (0)