From ead08827d05c6d292cb5953355dccc19553a1215 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Thu, 19 Jul 2018 00:23:10 +0100 Subject: [PATCH] Add more flexibility in testing errors in begin/complete phases (#13235) * Add more flexibility in testing errors in begin/complete phases * Update too --- .../src/createReactNoop.js | 32 ++++--------------- ...tIncrementalErrorHandling-test.internal.js | 6 ++-- .../ReactIncrementalErrorReplay-test.js | 6 ++-- .../__tests__/ReactProfiler-test.internal.js | 14 ++++---- 4 files changed, 17 insertions(+), 41 deletions(-) diff --git a/packages/react-noop-renderer/src/createReactNoop.js b/packages/react-noop-renderer/src/createReactNoop.js index 65af5f42d6..1505beb083 100644 --- a/packages/react-noop-renderer/src/createReactNoop.js +++ b/packages/react-noop-renderer/src/createReactNoop.js @@ -40,10 +40,7 @@ if (__DEV__) { function createReactNoop(reconciler: Function, useMutation: boolean) { let scheduledCallback = null; - let instanceCounter = 0; - let failInBeginPhase = false; - let failInCompletePhase = false; function appendChildToContainerOrInstance( parentInstance: Container | Instance, @@ -167,9 +164,6 @@ function createReactNoop(reconciler: Function, useMutation: boolean) { const sharedHostConfig = { getRootHostContext() { - if (failInBeginPhase) { - throw new Error('Error in host config.'); - } return NO_CONTEXT; }, @@ -182,7 +176,7 @@ function createReactNoop(reconciler: Function, useMutation: boolean) { }, createInstance(type: string, props: Props): Instance { - if (failInCompletePhase) { + if (type === 'errorInCompletePhase') { throw new Error('Error in host config.'); } const inst = { @@ -217,6 +211,9 @@ function createReactNoop(reconciler: Function, useMutation: boolean) { oldProps: Props, newProps: Props, ): null | {} { + if (type === 'errorInCompletePhase') { + throw new Error('Error in host config.'); + } if (oldProps === null) { throw new Error('Should have old props'); } @@ -227,6 +224,9 @@ function createReactNoop(reconciler: Function, useMutation: boolean) { }, shouldSetTextContent(type: string, props: Props): boolean { + if (type === 'errorInBeginPhase') { + throw new Error('Error in host config.'); + } return ( typeof props.children === 'string' || typeof props.children === 'number' ); @@ -695,24 +695,6 @@ function createReactNoop(reconciler: Function, useMutation: boolean) { console.log(...bufferedLog); }, - simulateErrorInHostConfigDuringBeginPhase(fn: () => void) { - failInBeginPhase = true; - try { - fn(); - } finally { - failInBeginPhase = false; - } - }, - - simulateErrorInHostConfigDuringCompletePhase(fn: () => void) { - failInCompletePhase = true; - try { - fn(); - } finally { - failInCompletePhase = false; - } - }, - flushWithoutCommitting( expectedFlush: Array, rootID: string = DEFAULT_ROOT_ID, diff --git a/packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js b/packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js index 8e1945f283..fd5b1c8a33 100644 --- a/packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js +++ b/packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js @@ -1212,10 +1212,8 @@ describe('ReactIncrementalErrorHandling', () => { }); it('handles error thrown by host config while working on failed root', () => { - ReactNoop.simulateErrorInHostConfigDuringBeginPhase(() => { - ReactNoop.render(); - expect(() => ReactNoop.flush()).toThrow('Error in host config.'); - }); + ReactNoop.render(); + expect(() => ReactNoop.flush()).toThrow('Error in host config.'); }); it('handles error thrown by top-level callback', () => { diff --git a/packages/react-reconciler/src/__tests__/ReactIncrementalErrorReplay-test.js b/packages/react-reconciler/src/__tests__/ReactIncrementalErrorReplay-test.js index 57bd42bc05..0ac3718d97 100644 --- a/packages/react-reconciler/src/__tests__/ReactIncrementalErrorReplay-test.js +++ b/packages/react-reconciler/src/__tests__/ReactIncrementalErrorReplay-test.js @@ -21,10 +21,8 @@ describe('ReactIncrementalErrorReplay', () => { }); it('should fail gracefully on error in the host environment', () => { - ReactNoop.simulateErrorInHostConfigDuringBeginPhase(() => { - ReactNoop.render(); - expect(() => ReactNoop.flush()).toThrow('Error in host config.'); - }); + ReactNoop.render(); + expect(() => ReactNoop.flush()).toThrow('Error in host config.'); }); it("should ignore error if it doesn't throw on retry", () => { diff --git a/packages/react/src/__tests__/ReactProfiler-test.internal.js b/packages/react/src/__tests__/ReactProfiler-test.internal.js index aca0d331d1..9c1bec7218 100644 --- a/packages/react/src/__tests__/ReactProfiler-test.internal.js +++ b/packages/react/src/__tests__/ReactProfiler-test.internal.js @@ -992,14 +992,12 @@ describe('Profiler', () => { // Simulate a renderer error during the "complete" phase. // This mimics behavior like React Native's View/Text nesting validation. - ReactNoop.simulateErrorInHostConfigDuringCompletePhase(() => { - ReactNoop.render( - - hi - , - ); - expect(ReactNoop.flush).toThrow('Error in host config.'); - }); + ReactNoop.render( + + hi + , + ); + expect(ReactNoop.flush).toThrow('Error in host config.'); // So long as the profiler timer's fiber stack is reset correctly, // Subsequent renders should not error.