Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Fizz] Add Component Stacks to onError and onPostpone when in dev mode or during prerenders in prod mode #27761

Merged
merged 1 commit into from Dec 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
53 changes: 45 additions & 8 deletions packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js
Expand Up @@ -734,7 +734,7 @@ describe('ReactDOMFizzServer', () => {

const theError = new Error('Test');
const loggedErrors = [];
function onError(x) {
function onError(x, errorInfo) {
loggedErrors.push(x);
return 'Hash of (' + x.message + ')';
}
Expand Down Expand Up @@ -837,7 +837,7 @@ describe('ReactDOMFizzServer', () => {

const theError = new Error('Test');
const loggedErrors = [];
function onError(x) {
function onError(x, errorInfo) {
loggedErrors.push(x);
return 'hash of (' + x.message + ')';
}
Expand Down Expand Up @@ -898,7 +898,7 @@ describe('ReactDOMFizzServer', () => {
[
theError.message,
expectedDigest,
componentStack(['Suspense', 'div', 'App']),
componentStack(['Lazy', 'Suspense', 'div', 'App']),
],
],
[
Expand Down Expand Up @@ -936,7 +936,9 @@ describe('ReactDOMFizzServer', () => {
return (
<div>
<Suspense fallback={<span>loading...</span>}>
<Erroring isClient={isClient} />
<Indirection level={2}>
<Erroring isClient={isClient} />
</Indirection>
</Suspense>
</div>
);
Expand Down Expand Up @@ -979,7 +981,15 @@ describe('ReactDOMFizzServer', () => {
[
theError.message,
expectedDigest,
componentStack(['Erroring', 'Suspense', 'div', 'App']),
componentStack([
'Erroring',
'Indirection',
'Indirection',
'Indirection',
'Suspense',
'div',
'App',
]),
],
],
[
Expand Down Expand Up @@ -1330,6 +1340,11 @@ describe('ReactDOMFizzServer', () => {
<AsyncText text="Hello" />
</h1>
</Suspense>
<main>
<Suspense fallback="loading...">
<AsyncText text="World" />
</Suspense>
</main>
</div>
);
}
Expand Down Expand Up @@ -1359,7 +1374,11 @@ describe('ReactDOMFizzServer', () => {
await waitForAll([]);

// We're still loading because we're waiting for the server to stream more content.
expect(getVisibleChildren(container)).toEqual(<div>Loading...</div>);
expect(getVisibleChildren(container)).toEqual(
<div>
Loading...<main>loading...</main>
</div>,
);

// We abort the server response.
await act(() => {
Expand All @@ -1374,26 +1393,44 @@ describe('ReactDOMFizzServer', () => {
[
'The server did not finish this Suspense boundary: The render was aborted by the server without a reason.',
expectedDigest,
// We get the stack of the task when it was aborted which is why we see `h1`
componentStack(['h1', 'Suspense', 'div', 'App']),
],
[
'The server did not finish this Suspense boundary: The render was aborted by the server without a reason.',
expectedDigest,
componentStack(['Suspense', 'main', 'div', 'App']),
],
],
[
[
'The server could not finish this Suspense boundary, likely due to an error during server rendering. Switched to client rendering.',
expectedDigest,
],
[
'The server could not finish this Suspense boundary, likely due to an error during server rendering. Switched to client rendering.',
expectedDigest,
],
],
);
expect(getVisibleChildren(container)).toEqual(<div>Loading...</div>);
expect(getVisibleChildren(container)).toEqual(
<div>
Loading...<main>loading...</main>
</div>,
);

// We now resolve it on the client.
await clientAct(() => resolveText('Hello'));
await clientAct(() => {
resolveText('Hello');
resolveText('World');
});
assertLog([]);

// The client rendered HTML is now in place.
expect(getVisibleChildren(container)).toEqual(
<div>
<h1>Hello</h1>
<main>World</main>
</div>,
);
});
Expand Down
10 changes: 7 additions & 3 deletions packages/react-dom/src/server/ReactDOMFizzServerBrowser.js
Expand Up @@ -7,7 +7,11 @@
* @flow
*/

import type {PostponedState} from 'react-server/src/ReactFizzServer';
import type {
PostponedState,
ErrorInfo,
PostponeInfo,
} from 'react-server/src/ReactFizzServer';
import type {ReactNodeList, ReactFormState} from 'shared/ReactTypes';
import type {
BootstrapScriptDescriptor,
Expand Down Expand Up @@ -42,8 +46,8 @@ type Options = {
bootstrapModules?: Array<string | BootstrapScriptDescriptor>,
progressiveChunkSize?: number,
signal?: AbortSignal,
onError?: (error: mixed) => ?string,
onPostpone?: (reason: string) => void,
onError?: (error: mixed, errorInfo: ErrorInfo) => ?string,
onPostpone?: (reason: string, postponeInfo: PostponeInfo) => void,
unstable_externalRuntimeSrc?: string | BootstrapScriptDescriptor,
importMap?: ImportMap,
formState?: ReactFormState<any, any> | null,
Expand Down
5 changes: 3 additions & 2 deletions packages/react-dom/src/server/ReactDOMFizzServerBun.js
Expand Up @@ -13,6 +13,7 @@ import type {
HeadersDescriptor,
} from 'react-dom-bindings/src/server/ReactFizzConfigDOM';
import type {ImportMap} from '../shared/ReactDOMTypes';
import type {ErrorInfo, PostponeInfo} from 'react-server/src/ReactFizzServer';

import ReactVersion from 'shared/ReactVersion';

Expand All @@ -39,8 +40,8 @@ type Options = {
bootstrapModules?: Array<string | BootstrapScriptDescriptor>,
progressiveChunkSize?: number,
signal?: AbortSignal,
onError?: (error: mixed) => ?string,
onPostpone?: (reason: string) => void,
onError?: (error: mixed, errorInfo: ErrorInfo) => ?string,
onPostpone?: (reason: string, postponeInfo: PostponeInfo) => void,
unstable_externalRuntimeSrc?: string | BootstrapScriptDescriptor,
importMap?: ImportMap,
formState?: ReactFormState<any, any> | null,
Expand Down
10 changes: 7 additions & 3 deletions packages/react-dom/src/server/ReactDOMFizzServerEdge.js
Expand Up @@ -7,7 +7,11 @@
* @flow
*/

import type {PostponedState} from 'react-server/src/ReactFizzServer';
import type {
PostponedState,
ErrorInfo,
PostponeInfo,
} from 'react-server/src/ReactFizzServer';
import type {ReactNodeList, ReactFormState} from 'shared/ReactTypes';
import type {
BootstrapScriptDescriptor,
Expand Down Expand Up @@ -42,8 +46,8 @@ type Options = {
bootstrapModules?: Array<string | BootstrapScriptDescriptor>,
progressiveChunkSize?: number,
signal?: AbortSignal,
onError?: (error: mixed) => ?string,
onPostpone?: (reason: string) => void,
onError?: (error: mixed, errorInfo: ErrorInfo) => ?string,
onPostpone?: (reason: string, postponeInfo: PostponeInfo) => void,
unstable_externalRuntimeSrc?: string | BootstrapScriptDescriptor,
importMap?: ImportMap,
formState?: ReactFormState<any, any> | null,
Expand Down
15 changes: 10 additions & 5 deletions packages/react-dom/src/server/ReactDOMFizzServerNode.js
Expand Up @@ -7,7 +7,12 @@
* @flow
*/

import type {Request, PostponedState} from 'react-server/src/ReactFizzServer';
import type {
Request,
PostponedState,
ErrorInfo,
PostponeInfo,
} from 'react-server/src/ReactFizzServer';
import type {ReactNodeList, ReactFormState} from 'shared/ReactTypes';
import type {Writable} from 'stream';
import type {
Expand Down Expand Up @@ -59,8 +64,8 @@ type Options = {
onShellReady?: () => void,
onShellError?: (error: mixed) => void,
onAllReady?: () => void,
onError?: (error: mixed) => ?string,
onPostpone?: (reason: string) => void,
onError?: (error: mixed, errorInfo: ErrorInfo) => ?string,
onPostpone?: (reason: string, postponeInfo: PostponeInfo) => void,
unstable_externalRuntimeSrc?: string | BootstrapScriptDescriptor,
importMap?: ImportMap,
formState?: ReactFormState<any, any> | null,
Expand All @@ -73,8 +78,8 @@ type ResumeOptions = {
onShellReady?: () => void,
onShellError?: (error: mixed) => void,
onAllReady?: () => void,
onError?: (error: mixed) => ?string,
onPostpone?: (reason: string) => void,
onError?: (error: mixed, errorInfo: ErrorInfo) => ?string,
onPostpone?: (reason: string, postponeInfo: PostponeInfo) => void,
};

type PipeableStream = {
Expand Down
10 changes: 7 additions & 3 deletions packages/react-dom/src/server/ReactDOMFizzStaticBrowser.js
Expand Up @@ -12,7 +12,11 @@ import type {
BootstrapScriptDescriptor,
HeadersDescriptor,
} from 'react-dom-bindings/src/server/ReactFizzConfigDOM';
import type {PostponedState} from 'react-server/src/ReactFizzServer';
import type {
PostponedState,
ErrorInfo,
PostponeInfo,
} from 'react-server/src/ReactFizzServer';
import type {ImportMap} from '../shared/ReactDOMTypes';

import ReactVersion from 'shared/ReactVersion';
Expand Down Expand Up @@ -40,8 +44,8 @@ type Options = {
bootstrapModules?: Array<string | BootstrapScriptDescriptor>,
progressiveChunkSize?: number,
signal?: AbortSignal,
onError?: (error: mixed) => ?string,
onPostpone?: (reason: string) => void,
onError?: (error: mixed, errorInfo: ErrorInfo) => ?string,
onPostpone?: (reason: string, postponeInfo: PostponeInfo) => void,
unstable_externalRuntimeSrc?: string | BootstrapScriptDescriptor,
importMap?: ImportMap,
onHeaders?: (headers: Headers) => void,
Expand Down
10 changes: 7 additions & 3 deletions packages/react-dom/src/server/ReactDOMFizzStaticEdge.js
Expand Up @@ -12,7 +12,11 @@ import type {
BootstrapScriptDescriptor,
HeadersDescriptor,
} from 'react-dom-bindings/src/server/ReactFizzConfigDOM';
import type {PostponedState} from 'react-server/src/ReactFizzServer';
import type {
PostponedState,
ErrorInfo,
PostponeInfo,
} from 'react-server/src/ReactFizzServer';
import type {ImportMap} from '../shared/ReactDOMTypes';

import ReactVersion from 'shared/ReactVersion';
Expand Down Expand Up @@ -40,8 +44,8 @@ type Options = {
bootstrapModules?: Array<string | BootstrapScriptDescriptor>,
progressiveChunkSize?: number,
signal?: AbortSignal,
onError?: (error: mixed) => ?string,
onPostpone?: (reason: string) => void,
onError?: (error: mixed, errorInfo: ErrorInfo) => ?string,
onPostpone?: (reason: string, postponeInfo: PostponeInfo) => void,
unstable_externalRuntimeSrc?: string | BootstrapScriptDescriptor,
importMap?: ImportMap,
onHeaders?: (headers: Headers) => void,
Expand Down
10 changes: 7 additions & 3 deletions packages/react-dom/src/server/ReactDOMFizzStaticNode.js
Expand Up @@ -12,7 +12,11 @@ import type {
BootstrapScriptDescriptor,
HeadersDescriptor,
} from 'react-dom-bindings/src/server/ReactFizzConfigDOM';
import type {PostponedState} from 'react-server/src/ReactFizzServer';
import type {
PostponedState,
ErrorInfo,
PostponeInfo,
} from 'react-server/src/ReactFizzServer';
import type {ImportMap} from '../shared/ReactDOMTypes';

import {Writable, Readable} from 'stream';
Expand Down Expand Up @@ -41,8 +45,8 @@ type Options = {
bootstrapModules?: Array<string | BootstrapScriptDescriptor>,
progressiveChunkSize?: number,
signal?: AbortSignal,
onError?: (error: mixed) => ?string,
onPostpone?: (reason: string) => void,
onError?: (error: mixed, errorInfo: ErrorInfo) => ?string,
onPostpone?: (reason: string, postponeInfo: PostponeInfo) => void,
unstable_externalRuntimeSrc?: string | BootstrapScriptDescriptor,
importMap?: ImportMap,
onHeaders?: (headers: HeadersDescriptor) => void,
Expand Down