@@ -16,6 +16,7 @@ let ReactNoop;
1616let ReactNoopFlightServer ;
1717let ReactNoopFlightClient ;
1818let ErrorBoundary ;
19+ let NoErrorExpected ;
1920
2021describe ( 'ReactFlight' , ( ) => {
2122 beforeEach ( ( ) => {
@@ -47,6 +48,26 @@ describe('ReactFlight', () => {
4748 return this . props . children ;
4849 }
4950 } ;
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+ } ;
5071 } ) ;
5172
5273 function moduleReference ( value ) {
@@ -164,6 +185,49 @@ describe('ReactFlight', () => {
164185 } ) ;
165186 } ) ;
166187
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+
167231 it ( 'should warn in DEV if a toJSON instance is passed to a host component' , ( ) => {
168232 expect ( ( ) => {
169233 const transport = ReactNoopFlightServer . render (
0 commit comments