@@ -16,6 +16,7 @@ let ReactNoop;
16
16
let ReactNoopFlightServer ;
17
17
let ReactNoopFlightClient ;
18
18
let ErrorBoundary ;
19
+ let NoErrorExpected ;
19
20
20
21
describe ( 'ReactFlight' , ( ) => {
21
22
beforeEach ( ( ) => {
@@ -47,6 +48,26 @@ describe('ReactFlight', () => {
47
48
return this . props . children ;
48
49
}
49
50
} ;
51
+
52
+ NoErrorExpected = class extends React . Component {
53
+ state = { hasError : false , error : null } ;
54
+ static getDerivedStateFromError ( error ) {
55
+ return {
56
+ hasError : true ,
57
+ error,
58
+ } ;
59
+ }
60
+ componentDidMount ( ) {
61
+ expect ( this . state . error ) . toBe ( null ) ;
62
+ expect ( this . state . hasError ) . toBe ( false ) ;
63
+ }
64
+ render ( ) {
65
+ if ( this . state . hasError ) {
66
+ return this . state . error . message ;
67
+ }
68
+ return this . props . children ;
69
+ }
70
+ } ;
50
71
} ) ;
51
72
52
73
function moduleReference ( value ) {
@@ -164,6 +185,49 @@ describe('ReactFlight', () => {
164
185
} ) ;
165
186
} ) ;
166
187
188
+ it ( 'should trigger the inner most error boundary inside a client component' , ( ) => {
189
+ function ServerComponent ( ) {
190
+ throw new Error ( 'This was thrown in the server component.' ) ;
191
+ }
192
+
193
+ function ClientComponent ( { children} ) {
194
+ // This should catch the error thrown by the server component, even though it has already happened.
195
+ // We currently need to wrap it in a div because as it's set up right now, a lazy reference will
196
+ // throw during reconciliation which will trigger the parent of the error boundary.
197
+ // This is similar to how these will suspend the parent if it's a direct child of a Suspense boundary.
198
+ // That's a bug.
199
+ return (
200
+ < ErrorBoundary expectedMessage = "This was thrown in the server component." >
201
+ < div > { children } </ div >
202
+ </ ErrorBoundary >
203
+ ) ;
204
+ }
205
+
206
+ const ClientComponentReference = moduleReference ( ClientComponent ) ;
207
+
208
+ function Server ( ) {
209
+ return (
210
+ < ClientComponentReference >
211
+ < ServerComponent />
212
+ </ ClientComponentReference >
213
+ ) ;
214
+ }
215
+
216
+ const data = ReactNoopFlightServer . render ( < Server /> ) ;
217
+
218
+ function Client ( { transport} ) {
219
+ return ReactNoopFlightClient . read ( transport ) ;
220
+ }
221
+
222
+ act ( ( ) => {
223
+ ReactNoop . render (
224
+ < NoErrorExpected >
225
+ < Client transport = { data } />
226
+ </ NoErrorExpected > ,
227
+ ) ;
228
+ } ) ;
229
+ } ) ;
230
+
167
231
it ( 'should warn in DEV if a toJSON instance is passed to a host component' , ( ) => {
168
232
expect ( ( ) => {
169
233
const transport = ReactNoopFlightServer . render (
0 commit comments