Skip to content

Commit

Permalink
Give unresolved lazy() a name in component stack (#16104)
Browse files Browse the repository at this point in the history
* Give unresolved lazy() a name in component stack

* Normalize stack in tests

Co-authored-by: Sebastian Markbage <sema@fb.com>
  • Loading branch information
motiz88 and sebmarkbage committed May 1, 2020
1 parent 333deb7 commit 3c7d52c
Showing 1 changed file with 90 additions and 0 deletions.
90 changes: 90 additions & 0 deletions packages/react-reconciler/src/__tests__/ReactLazy-test.internal.js
Expand Up @@ -6,6 +6,15 @@ let ReactFeatureFlags;
let Suspense;
let lazy;

function normalizeCodeLocInfo(str) {
return (
str &&
str.replace(/\n +(?:at|in) ([\S]+)[^\n]*/g, function(m, name) {
return '\n in ' + name + ' (at **)';
})
);
}

describe('ReactLazy', () => {
beforeEach(() => {
jest.resetModules();
Expand Down Expand Up @@ -1183,4 +1192,85 @@ describe('ReactLazy', () => {
expect(Scheduler).toFlushAndYield([]);
}).toErrorDev('Function components cannot be given refs');
});

it('should error with a component stack naming the resolved component', async () => {
let componentStackMessage;

const LazyText = lazy(() =>
fakeImport(function ResolvedText() {
throw new Error('oh no');
}),
);

class ErrorBoundary extends React.Component {
state = {error: null};

componentDidCatch(error, errMessage) {
componentStackMessage = normalizeCodeLocInfo(errMessage.componentStack);
this.setState({
error,
});
}

render() {
return this.state.error ? null : this.props.children;
}
}

ReactTestRenderer.create(
<ErrorBoundary>
<Suspense fallback={<Text text="Loading..." />}>
<LazyText text="Hi" />
</Suspense>
</ErrorBoundary>,
{unstable_isConcurrent: true},
);

expect(Scheduler).toFlushAndYield(['Loading...']);

try {
await Promise.resolve();
} catch (e) {}

expect(Scheduler).toFlushAndYield([]);

expect(componentStackMessage).toContain('in ResolvedText');
});

it('should error with a component stack containing Lazy if unresolved', () => {
let componentStackMessage;

const LazyText = lazy(() => ({
then(resolve, reject) {
reject(new Error('oh no'));
},
}));

class ErrorBoundary extends React.Component {
state = {error: null};

componentDidCatch(error, errMessage) {
componentStackMessage = normalizeCodeLocInfo(errMessage.componentStack);
this.setState({
error,
});
}

render() {
return this.state.error ? null : this.props.children;
}
}

ReactTestRenderer.create(
<ErrorBoundary>
<Suspense fallback={<Text text="Loading..." />}>
<LazyText text="Hi" />
</Suspense>
</ErrorBoundary>,
);

expect(Scheduler).toHaveYielded([]);

expect(componentStackMessage).toContain('in Lazy');
});
});

0 comments on commit 3c7d52c

Please sign in to comment.