Skip to content

Commit

Permalink
Replace ReactFiberErrorLogger injection with static forks (#11717)
Browse files Browse the repository at this point in the history
  • Loading branch information
gaearon authored Nov 30, 2017
1 parent 060581b commit 642a678
Show file tree
Hide file tree
Showing 10 changed files with 71 additions and 62 deletions.
3 changes: 0 additions & 3 deletions packages/react-dom/src/client/ReactDOMFB.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@

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

Expand All @@ -25,7 +23,6 @@ Object.assign(
// These are real internal dependencies that are trickier to remove:
ReactBrowserEventEmitter,
ReactErrorUtils,
ReactFiberErrorLogger,
ReactFiberTreeReflection,
ReactDOMComponentTree,
ReactInstanceMap,
Expand Down
7 changes: 0 additions & 7 deletions packages/react-native-renderer/src/ReactNativeRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ import type {ReactNodeList} from 'shared/ReactTypes';

import './ReactNativeInjection';

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

import {showDialog} from './ReactNativeFiberErrorDialog';
import NativeMethodsMixin from './NativeMethodsMixin';
import ReactNativeBridgeEventPlugin from './ReactNativeBridgeEventPlugin';
import ReactNativeComponent from './ReactNativeComponent';
Expand All @@ -40,10 +37,6 @@ ReactGenericBatching.injection.injectFiberBatchedUpdates(

const roots = new Map();

// Intercept lifecycle errors and ensure they are shown with the correct stack
// trace within the native redbox component.
ReactFiberErrorLogger.injection.injectDialog(showDialog);

const ReactNativeRenderer: ReactNativeType = {
NativeComponent: ReactNativeComponent,

Expand Down
17 changes: 17 additions & 0 deletions packages/react-reconciler/src/ReactFiberErrorDialog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

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

// This module is forked in different environments.
// By default, return `true` to log errors to the console.
// Forks can return `false` if this isn't desirable.
export function showErrorDialog(capturedError: CapturedError): boolean {
return true;
}
28 changes: 3 additions & 25 deletions packages/react-reconciler/src/ReactFiberErrorLogger.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,12 @@

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

import invariant from 'fbjs/lib/invariant';

const defaultShowDialog = (capturedError: CapturedError) => true;

let showDialog = defaultShowDialog;
import {showErrorDialog} from './ReactFiberErrorDialog';

export function logCapturedError(capturedError: CapturedError): void {
const logError = showDialog(capturedError);
const logError = showErrorDialog(capturedError);

// Allow injected showDialog() to prevent default console.error logging.
// Allow injected showErrorDialog() to prevent default console.error logging.
// This enables renderers like ReactNative to better manage redbox behavior.
if (logError === false) {
return;
Expand Down Expand Up @@ -78,21 +74,3 @@ export function logCapturedError(capturedError: CapturedError): void {
console.error(error);
}
}

export const injection = {
/**
* Display custom dialog for lifecycle errors.
* Return false to prevent default behavior of logging to console.error.
*/
injectDialog(fn: (e: CapturedError) => boolean) {
invariant(
showDialog === defaultShowDialog,
'The custom dialog was already injected.',
);
invariant(
typeof fn === 'function',
'Injected showDialog() must be a function.',
);
showDialog = fn;
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @flow
*/

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

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

let errorToHandle: Error;
Expand Down
17 changes: 17 additions & 0 deletions packages/react-reconciler/src/forks/ReactFiberErrorDialog.www.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

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

// Provided by www
const ReactFiberErrorDialogWWW = require('ReactFiberErrorDialog');

export function showErrorDialog(capturedError: CapturedError): boolean {
return ReactFiberErrorDialogWWW.showErrorDialog(capturedError);
}
7 changes: 0 additions & 7 deletions packages/react-rt-renderer/src/ReactNativeRT.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ import type {ReactNodeList} from 'shared/ReactTypes';
import 'InitializeCore';
import './ReactNativeRTEventEmitter';

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

const roots = new Map();

// Intercept lifecycle errors and ensure they are shown with the correct stack
// trace within the native redbox component.
ReactFiberErrorLogger.injection.injectDialog(showDialog);

const ReactNativeRTFiber: ReactNativeRTType = {
render(element: React$Element<any>, containerTag: any, callback: ?Function) {
let root = roots.get(containerTag);
Expand Down
9 changes: 8 additions & 1 deletion scripts/flow/environment.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,14 @@ declare var __REACT_DEVTOOLS_GLOBAL_HOOK__: any; /*?{
inject: ?((stuff: Object) => void)
};*/

// ReactFeatureFlags rollup shim for www imports the www implementation.
// ReactFeatureFlags www fork
declare module 'ReactFeatureFlags' {
declare module.exports: any;
}

// ReactFiberErrorDialog www fork
declare module 'ReactFiberErrorDialog' {
declare module.exports: {
showErrorDialog: (error: mixed) => boolean,
};
}
24 changes: 24 additions & 0 deletions scripts/rollup/forks.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ const UMD_DEV = bundleTypes.UMD_DEV;
const UMD_PROD = bundleTypes.UMD_PROD;
const FB_DEV = bundleTypes.FB_DEV;
const FB_PROD = bundleTypes.FB_PROD;
const RN_DEV = bundleTypes.RN_DEV;
const RN_PROD = bundleTypes.RN_PROD;

// If you need to replace a file with another file for a specific environment,
// add it to this list with the logic for choosing the right replacement.
Expand Down Expand Up @@ -66,6 +68,28 @@ const forks = Object.freeze({
return null;
}
},

// Different behavior for caught errors.
'react-reconciler/src/ReactFiberErrorDialog': (bundleType, entry) => {
switch (bundleType) {
case FB_DEV:
case FB_PROD:
// Use the www fork which shows an error dialog.
return 'react-reconciler/src/forks/ReactFiberErrorDialog.www.js';
case RN_DEV:
case RN_PROD:
switch (entry) {
case 'react-native-renderer':
case 'react-rt-renderer':
// Use the RN fork which plays well with redbox.
return 'react-reconciler/src/forks/ReactFiberErrorDialog.native.js';
default:
return null;
}
default:
return null;
}
},
});

module.exports = forks;
17 changes: 0 additions & 17 deletions scripts/rollup/shims/facebook-www/ReactFiberErrorLogger.js

This file was deleted.

0 comments on commit 642a678

Please sign in to comment.