Skip to content

Commit 425ff2e

Browse files
sebmarkbageAndyPengc12
authored andcommitted
[Fizz] Align recoverable error serialization in dev mode (facebook#28340)
Same as facebook#28327 but for Fizz. One thing that's weird about this recoverable error is that we don't send the regular stack for it, just the component stack it seems. This is missing some potential information and if we move toward integrated since stacks it would be one thing.
1 parent 3e128f2 commit 425ff2e

File tree

5 files changed

+26
-28
lines changed

5 files changed

+26
-28
lines changed

packages/react-client/src/__tests__/ReactFlight-test.js

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,11 @@ describe('ReactFlight', () => {
8585
);
8686
let expectedDigest = this.props.expectedMessage;
8787
if (
88-
expectedDigest.startsWith('Error: {') ||
89-
expectedDigest.startsWith('Error: <')
88+
expectedDigest.startsWith('{') ||
89+
expectedDigest.startsWith('<')
9090
) {
9191
expectedDigest = '{}';
92-
} else if (expectedDigest.startsWith('Error: [')) {
92+
} else if (expectedDigest.startsWith('[')) {
9393
expectedDigest = '[]';
9494
}
9595
expect(this.state.error.digest).toContain(expectedDigest);
@@ -799,12 +799,12 @@ describe('ReactFlight', () => {
799799
<Throw value={new TypeError('This is a real Error.')} />
800800
</div>
801801
</ClientErrorBoundary>
802-
<ClientErrorBoundary expectedMessage="Error: This is a string error.">
802+
<ClientErrorBoundary expectedMessage="This is a string error.">
803803
<div>
804804
<Throw value="This is a string error." />
805805
</div>
806806
</ClientErrorBoundary>
807-
<ClientErrorBoundary expectedMessage="Error: {message: ..., extra: ..., nested: ...}">
807+
<ClientErrorBoundary expectedMessage="{message: ..., extra: ..., nested: ...}">
808808
<div>
809809
<Throw
810810
value={{
@@ -816,9 +816,7 @@ describe('ReactFlight', () => {
816816
</div>
817817
</ClientErrorBoundary>
818818
<ClientErrorBoundary
819-
expectedMessage={
820-
'Error: {message: "Short", extra: ..., nested: ...}'
821-
}>
819+
expectedMessage={'{message: "Short", extra: ..., nested: ...}'}>
822820
<div>
823821
<Throw
824822
value={{
@@ -829,32 +827,32 @@ describe('ReactFlight', () => {
829827
/>
830828
</div>
831829
</ClientErrorBoundary>
832-
<ClientErrorBoundary expectedMessage="Error: Symbol(hello)">
830+
<ClientErrorBoundary expectedMessage="Symbol(hello)">
833831
<div>
834832
<Throw value={Symbol('hello')} />
835833
</div>
836834
</ClientErrorBoundary>
837-
<ClientErrorBoundary expectedMessage="Error: 123">
835+
<ClientErrorBoundary expectedMessage="123">
838836
<div>
839837
<Throw value={123} />
840838
</div>
841839
</ClientErrorBoundary>
842-
<ClientErrorBoundary expectedMessage="Error: undefined">
840+
<ClientErrorBoundary expectedMessage="undefined">
843841
<div>
844842
<Throw value={undefined} />
845843
</div>
846844
</ClientErrorBoundary>
847-
<ClientErrorBoundary expectedMessage="Error: <div/>">
845+
<ClientErrorBoundary expectedMessage="<div/>">
848846
<div>
849847
<Throw value={<div />} />
850848
</div>
851849
</ClientErrorBoundary>
852-
<ClientErrorBoundary expectedMessage="Error: function Foo() {}">
850+
<ClientErrorBoundary expectedMessage="function Foo() {}">
853851
<div>
854852
<Throw value={function Foo() {}} />
855853
</div>
856854
</ClientErrorBoundary>
857-
<ClientErrorBoundary expectedMessage={'Error: ["array"]'}>
855+
<ClientErrorBoundary expectedMessage={'["array"]'}>
858856
<div>
859857
<Throw value={['array']} />
860858
</div>
@@ -874,7 +872,7 @@ describe('ReactFlight', () => {
874872
} else if (typeof x === 'object' && x !== null) {
875873
return `digest({})`;
876874
}
877-
return `digest(Error: ${String(x)})`;
875+
return `digest(${String(x)})`;
878876
},
879877
});
880878

packages/react-server-dom-webpack/src/__tests__/ReactFlightDOM-test.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -919,9 +919,7 @@ describe('ReactFlightDOM', () => {
919919
abort('for reasons');
920920
});
921921
if (__DEV__) {
922-
expect(container.innerHTML).toBe(
923-
'<p>Error: for reasons + a dev digest</p>',
924-
);
922+
expect(container.innerHTML).toBe('<p>for reasons + a dev digest</p>');
925923
} else {
926924
expect(container.innerHTML).toBe('<p>digest("for reasons")</p>');
927925
}

packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMBrowser-test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -583,7 +583,7 @@ describe('ReactFlightDOMBrowser', () => {
583583
controller.abort('for reasons');
584584
});
585585
const expectedValue = __DEV__
586-
? '<p>Error: for reasons + a dev digest</p>'
586+
? '<p>for reasons + a dev digest</p>'
587587
: '<p>digest("for reasons")</p>';
588588
expect(container.innerHTML).toBe(expectedValue);
589589

packages/react-server/src/ReactFizzServer.js

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import type {ComponentStackNode} from './ReactFizzComponentStack';
3333
import type {TreeContext} from './ReactFizzTreeContext';
3434
import type {ThenableState} from './ReactFizzThenable';
3535
import {enableRenderableContext} from 'shared/ReactFeatureFlags';
36+
import {describeObjectForErrorMessage} from 'shared/ReactSerializationErrors';
3637

3738
import {
3839
scheduleWork,
@@ -816,18 +817,19 @@ function encodeErrorForBoundary(
816817
) {
817818
boundary.errorDigest = digest;
818819
if (__DEV__) {
820+
let message;
819821
// In dev we additionally encode the error message and component stack on the boundary
820-
let errorMessage;
821-
if (typeof error === 'string') {
822-
errorMessage = error;
823-
} else if (error && typeof error.message === 'string') {
824-
errorMessage = error.message;
822+
if (error instanceof Error) {
823+
// eslint-disable-next-line react-internal/safe-string-coercion
824+
message = String(error.message);
825+
} else if (typeof error === 'object' && error !== null) {
826+
message = describeObjectForErrorMessage(error);
825827
} else {
826828
// eslint-disable-next-line react-internal/safe-string-coercion
827-
errorMessage = String(error);
829+
message = String(error);
828830
}
829831

830-
boundary.errorMessage = errorMessage;
832+
boundary.errorMessage = message;
831833
boundary.errorComponentStack = thrownInfo.componentStack;
832834
}
833835
}

packages/react-server/src/ReactFlightServer.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1678,10 +1678,10 @@ function emitErrorChunk(
16781678
// eslint-disable-next-line react-internal/safe-string-coercion
16791679
stack = String(error.stack);
16801680
} else if (typeof error === 'object' && error !== null) {
1681-
message = 'Error: ' + describeObjectForErrorMessage(error);
1681+
message = describeObjectForErrorMessage(error);
16821682
} else {
16831683
// eslint-disable-next-line react-internal/safe-string-coercion
1684-
message = 'Error: ' + String(error);
1684+
message = String(error);
16851685
}
16861686
} catch (x) {
16871687
message = 'An error occurred but serializing the error message failed.';

0 commit comments

Comments
 (0)