@samitouri / QOS-React / commits / c84b9bf828

Tweak error message for missing fallback (#14068)

Sophie Alpert committed Nov 1, 2018 at 22:45 UTC c84b9bf828c38e0b24042ebb9cd859292146a6fb
4 files changed +26 -4
packages/react-reconciler/src/ReactCurrentFiber.js
+2
@@ -17,6 +17,7 @@ import {
17 HostComponent,
18 Mode,
19 LazyComponent,
20 + SuspenseComponent,
21 } from 'shared/ReactWorkTags';
22 import describeComponentFrame from 'shared/describeComponentFrame';
23 import getComponentName from 'shared/getComponentName';
@@ -33,6 +34,7 @@ function describeFiber(fiber: Fiber): string {
34 case ClassComponent:
35 case HostComponent:
36 case Mode:
37 + case SuspenseComponent:
38 const owner = fiber._debugOwner;
39 const source = fiber._debugSource;
40 const name = getComponentName(fiber.type);
packages/react-reconciler/src/ReactFiberUnwindWork.js
+8 -1
@@ -46,6 +46,7 @@ import {
46 CaptureUpdate,
47 } from './ReactUpdateQueue';
48 import {logError} from './ReactFiberCommitWork';
49 +import {getStackByFiberInDevAndProd} from './ReactCurrentFiber';
50 import {popHostContainer, popHostContext} from './ReactFiberHostContext';
51 import {
52 isContextProvider as isLegacyContextProvider,
@@ -315,8 +316,14 @@ function throwException(
316 workInProgress = workInProgress.return;
317 } while (workInProgress !== null);
318 // No boundary was found. Fallthrough to error mode.
319 + // TODO: Use invariant so the message is stripped in prod?
320 value = new Error(
319 - 'An update was suspended, but no placeholder UI was provided.',
321 + (getComponentName(sourceFiber.type) || 'A React component') +
322 + ' suspended while rendering, but no fallback UI was specified.\n' +
323 + '\n' +
324 + 'Add a <Suspense fallback=...> component higher in the tree to ' +
325 + 'provide a loading indicator or placeholder to display.' +
326 + getStackByFiberInDevAndProd(sourceFiber),
327 );
328 }
329
packages/react-reconciler/src/__tests__/ReactSuspense-test.internal.js
+13 -2
@@ -312,8 +312,19 @@ describe('ReactSuspense', () => {
312 },
313 );
314
315 - expect(root).toFlushAndThrow(
316 - 'An update was suspended, but no placeholder UI was provided.',
315 + let err;
316 + try {
317 + root.unstable_flushAll();
318 + } catch (e) {
319 + err = e;
320 + }
321 + expect(err.message.replace(/at .+?:\d+/g, 'at **')).toBe(
322 + 'AsyncText suspended while rendering, but no fallback UI was specified.\n' +
323 + '\n' +
324 + 'Add a <Suspense fallback=...> component higher in the tree to provide ' +
325 + 'a loading indicator or placeholder to display.\n' +
326 + (__DEV__ ? ' in AsyncText (at **)\n' : ' in AsyncText\n') +
327 + (__DEV__ ? ' in Suspense (at **)' : ' in Suspense'),
328 );
329 expect(ReactTestRenderer).toHaveYielded(['Suspend! [Hi]', 'Suspend! [Hi]']);
330 });
packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.internal.js
+3 -1
@@ -652,7 +652,9 @@ describe('ReactSuspenseWithNoopRenderer', () => {
652 it('throws a helpful error when an update is suspends without a placeholder', () => {
653 expect(() => {
654 ReactNoop.flushSync(() => ReactNoop.render(<AsyncText text="Async" />));
655 - }).toThrow('An update was suspended, but no placeholder UI was provided.');
655 + }).toThrow(
656 + 'AsyncText suspended while rendering, but no fallback UI was specified.',
657 + );
658 });
659
660 it('a Suspense component correctly handles more than one suspended child', async () => {