Replace ReactFiberErrorLogger injection with static forks (#11717)
Dan Abramov committed
Nov 30, 2017 at 17:57 UTC
642a678a80af9c2350aea2f8c816085b1aa98d45
10 files changed
+71
-62
packages/react-dom/src/client/ReactDOMFB.js
-3
@@ -9,8 +9,6 @@
9
10
import * as ReactFiberTreeReflection from 'react-reconciler/reflection';
11
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';
12
import ReactErrorUtils from 'shared/ReactErrorUtils';
13
import {addUserTimingListener} from 'shared/ReactFeatureFlags';
14
@@ -25,7 +23,6 @@ Object.assign(
23
// These are real internal dependencies that are trickier to remove:
24
ReactBrowserEventEmitter,
25
ReactErrorUtils,
28
- ReactFiberErrorLogger,
26
ReactFiberTreeReflection,
27
ReactDOMComponentTree,
28
ReactInstanceMap,
packages/react-native-renderer/src/ReactNativeRenderer.js
-7
@@ -12,8 +12,6 @@ import type {ReactNodeList} from 'shared/ReactTypes';
12
13
import './ReactNativeInjection';
14
15
-// TODO: direct imports like some-package/src/* are bad. Fix me.
16
-import * as ReactFiberErrorLogger from 'react-reconciler/src/ReactFiberErrorLogger';
15
import * as ReactPortal from 'react-reconciler/src/ReactPortal';
16
import * as ReactGenericBatching from 'events/ReactGenericBatching';
17
import TouchHistoryMath from 'events/TouchHistoryMath';
@@ -22,7 +20,6 @@ import ReactVersion from 'shared/ReactVersion';
20
// Module provided by RN:
21
import UIManager from 'UIManager';
22
25
-import {showDialog} from './ReactNativeFiberErrorDialog';
23
import NativeMethodsMixin from './NativeMethodsMixin';
24
import ReactNativeBridgeEventPlugin from './ReactNativeBridgeEventPlugin';
25
import ReactNativeComponent from './ReactNativeComponent';
@@ -40,10 +37,6 @@ ReactGenericBatching.injection.injectFiberBatchedUpdates(
37
38
const roots = new Map();
39
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
-
40
const ReactNativeRenderer: ReactNativeType = {
41
NativeComponent: ReactNativeComponent,
42
packages/react-reconciler/src/ReactFiberErrorDialog.js
new
+17
@@ -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
+3
-25
@@ -9,16 +9,12 @@
9
10
import type {CapturedError} from './ReactFiberScheduler';
11
12
-import invariant from 'fbjs/lib/invariant';
13
-
14
-const defaultShowDialog = (capturedError: CapturedError) => true;
15
-
16
-let showDialog = defaultShowDialog;
12
+import {showErrorDialog} from './ReactFiberErrorDialog';
13
14
export function logCapturedError(capturedError: CapturedError): void {
19
- const logError = showDialog(capturedError);
15
+ const logError = showErrorDialog(capturedError);
16
21
- // Allow injected showDialog() to prevent default console.error logging.
17
+ // Allow injected showErrorDialog() to prevent default console.error logging.
18
// This enables renderers like ReactNative to better manage redbox behavior.
19
if (logError === false) {
20
return;
@@ -78,21 +74,3 @@ export function logCapturedError(capturedError: CapturedError): void {
74
console.error(error);
75
}
76
}
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-reconciler/src/forks/ReactFiberErrorDialog.native.js
renamed
+2
-2
@@ -7,7 +7,7 @@
7
* @flow
8
*/
9
10
-import type {CapturedError} from 'react-reconciler/src/ReactFiberScheduler';
10
+import type {CapturedError} from '../ReactFiberScheduler';
11
12
// Module provided by RN:
13
import ExceptionsManager from 'ExceptionsManager';
@@ -16,7 +16,7 @@ import ExceptionsManager from 'ExceptionsManager';
16
* Intercept lifecycle errors and ensure they are shown with the correct stack
17
* trace within the native redbox component.
18
*/
19
-export function showDialog(capturedError: CapturedError): boolean {
19
+export function showErrorDialog(capturedError: CapturedError): boolean {
20
const {componentStack, error} = capturedError;
21
22
let errorToHandle: Error;
packages/react-reconciler/src/forks/ReactFiberErrorDialog.www.js
new
+17
@@ -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
-7
@@ -19,9 +19,6 @@ import type {ReactNodeList} from 'shared/ReactTypes';
19
import 'InitializeCore';
20
import './ReactNativeRTEventEmitter';
21
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';
22
import * as ReactPortal from 'react-reconciler/src/ReactPortal';
23
import * as ReactGenericBatching from 'events/ReactGenericBatching';
24
import ReactVersion from 'shared/ReactVersion';
@@ -36,10 +33,6 @@ ReactGenericBatching.injection.injectFiberBatchedUpdates(
33
34
const roots = new Map();
35
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
-
36
const ReactNativeRTFiber: ReactNativeRTType = {
37
render(element: React$Element<any>, containerTag: any, callback: ?Function) {
38
let root = roots.get(containerTag);
scripts/flow/environment.js
+8
-1
@@ -13,7 +13,14 @@ declare var __REACT_DEVTOOLS_GLOBAL_HOOK__: any; /*?{
13
inject: ?((stuff: Object) => void)
14
};*/
15
16
-// ReactFeatureFlags rollup shim for www imports the www implementation.
16
+// ReactFeatureFlags www fork
17
declare module 'ReactFeatureFlags' {
18
declare module.exports: any;
19
}
20
+
21
+// ReactFiberErrorDialog www fork
22
+declare module 'ReactFiberErrorDialog' {
23
+ declare module.exports: {
24
+ showErrorDialog: (error: mixed) => boolean,
25
+ };
26
+}
scripts/rollup/forks.js
+24
@@ -6,6 +6,8 @@ const UMD_DEV = bundleTypes.UMD_DEV;
6
const UMD_PROD = bundleTypes.UMD_PROD;
7
const FB_DEV = bundleTypes.FB_DEV;
8
const FB_PROD = bundleTypes.FB_PROD;
9
+const RN_DEV = bundleTypes.RN_DEV;
10
+const RN_PROD = bundleTypes.RN_PROD;
11
12
// If you need to replace a file with another file for a specific environment,
13
// add it to this list with the logic for choosing the right replacement.
@@ -66,6 +68,28 @@ const forks = Object.freeze({
68
return null;
69
}
70
},
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
+ },
93
});
94
95
module.exports = forks;
scripts/rollup/shims/facebook-www/ReactFiberErrorLogger.js
deleted
-17
@@ -1,17 +0,0 @@
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
- * @providesModule ReactFiberErrorLogger
8
- */
9
-
10
-'use strict';
11
-
12
-const {
13
- __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
14
-} = require('ReactDOM-fb');
15
-
16
-module.exports =
17
- __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactFiberErrorLogger;