@@ -90,46 +90,28 @@ describe('ReactDOMFizzServer', () => {
90
90
} ) ;
91
91
92
92
function expectErrors ( errorsArr , toBeDevArr , toBeProdArr ) {
93
- const mappedErrows = errorsArr . map ( error => {
94
- if ( error . componentStack ) {
95
- return [
96
- error . message ,
97
- error . hash ,
98
- normalizeCodeLocInfo ( error . componentStack ) ,
99
- ] ;
100
- } else if ( error . hash ) {
101
- return [ error . message , error . hash ] ;
93
+ const mappedErrows = errorsArr . map ( ( { error, errorInfo} ) => {
94
+ const stack = errorInfo && errorInfo . componentStack ;
95
+ const errorHash = errorInfo && errorInfo . errorHash ;
96
+ if ( stack ) {
97
+ return [ error . message , errorHash , normalizeCodeLocInfo ( stack ) ] ;
98
+ } else if ( errorHash ) {
99
+ return [ error . message , errorHash ] ;
102
100
}
103
101
return error . message ;
104
102
} ) ;
105
103
if ( __DEV__ ) {
106
- expect ( mappedErrows ) . toEqual (
107
- toBeDevArr ,
108
- // .map(([errorMessage, errorHash, errorComponentStack]) => {
109
- // if (typeof error === 'string' || error instanceof String) {
110
- // return error;
111
- // }
112
- // let str = JSON.stringify(error).replace(/\\n/g, '\n');
113
- // // this gets stripped away by normalizeCodeLocInfo...
114
- // // Kind of hacky but lets strip it away here too just so they match...
115
- // // easier than fixing the regex to account for this edge case
116
- // if (str.endsWith('at **)" }')) {
117
- // str = str.replace(/at \*\*\)\" }$/, 'at **)');
118
- // }
119
- // return str;
120
- // }),
121
- ) ;
104
+ expect ( mappedErrows ) . toEqual ( toBeDevArr ) ;
122
105
} else {
123
106
expect ( mappedErrows ) . toEqual ( toBeProdArr ) ;
124
107
}
125
108
}
126
109
127
- // @TODO we will use this in a followup change once we start exposing componentStacks from server errors
128
- // function componentStack(components) {
129
- // return components
130
- // .map(component => `\n in ${component} (at **)`)
131
- // .join('');
132
- // }
110
+ function componentStack ( components ) {
111
+ return components
112
+ . map ( component => `\n in ${ component } (at **)` )
113
+ . join ( '' ) ;
114
+ }
133
115
134
116
async function act ( callback ) {
135
117
await callback ( ) ;
@@ -471,8 +453,8 @@ describe('ReactDOMFizzServer', () => {
471
453
bootstrapped = true ;
472
454
// Attempt to hydrate the content.
473
455
ReactDOMClient . hydrateRoot ( container , < App isClient = { true } /> , {
474
- onRecoverableError ( error ) {
475
- errors . push ( error ) ;
456
+ onRecoverableError ( error , errorInfo ) {
457
+ errors . push ( { error, errorInfo } ) ;
476
458
} ,
477
459
} ) ;
478
460
} ;
@@ -483,8 +465,8 @@ describe('ReactDOMFizzServer', () => {
483
465
loggedErrors . push ( x ) ;
484
466
return 'Hash of (' + x . message + ')' ;
485
467
}
486
- // const expectedHash = onError(theError);
487
- // loggedErrors.length = 0;
468
+ const expectedHash = onError ( theError ) ;
469
+ loggedErrors . length = 0 ;
488
470
489
471
await act ( async ( ) => {
490
472
const { pipe} = ReactDOMFizzServer . renderToPipeableStream (
@@ -519,9 +501,18 @@ describe('ReactDOMFizzServer', () => {
519
501
expect ( Scheduler ) . toFlushAndYield ( [ ] ) ;
520
502
expectErrors (
521
503
errors ,
522
- [ theError . message ] ,
523
504
[
524
- 'The server could not finish this Suspense boundary, likely due to an error during server rendering. Switched to client rendering.' ,
505
+ [
506
+ theError . message ,
507
+ expectedHash ,
508
+ componentStack ( [ 'Lazy' , 'Suspense' , 'div' , 'App' ] ) ,
509
+ ] ,
510
+ ] ,
511
+ [
512
+ [
513
+ 'The server could not finish this Suspense boundary, likely due to an error during server rendering. Switched to client rendering.' ,
514
+ expectedHash ,
515
+ ] ,
525
516
] ,
526
517
) ;
527
518
@@ -577,8 +568,8 @@ describe('ReactDOMFizzServer', () => {
577
568
loggedErrors . push ( x ) ;
578
569
return 'hash of (' + x . message + ')' ;
579
570
}
580
- // const expectedHash = onError(theError);
581
- // loggedErrors.length = 0;
571
+ const expectedHash = onError ( theError ) ;
572
+ loggedErrors . length = 0 ;
582
573
583
574
function App ( { isClient} ) {
584
575
return (
@@ -605,8 +596,8 @@ describe('ReactDOMFizzServer', () => {
605
596
const errors = [ ] ;
606
597
// Attempt to hydrate the content.
607
598
ReactDOMClient . hydrateRoot ( container , < App isClient = { true } /> , {
608
- onRecoverableError ( error ) {
609
- errors . push ( error ) ;
599
+ onRecoverableError ( error , errorInfo ) {
600
+ errors . push ( { error, errorInfo } ) ;
610
601
} ,
611
602
} ) ;
612
603
Scheduler . unstable_flushAll ( ) ;
@@ -630,9 +621,18 @@ describe('ReactDOMFizzServer', () => {
630
621
631
622
expectErrors (
632
623
errors ,
633
- [ theError . message ] ,
634
624
[
635
- 'The server could not finish this Suspense boundary, likely due to an error during server rendering. Switched to client rendering.' ,
625
+ [
626
+ theError . message ,
627
+ expectedHash ,
628
+ componentStack ( [ 'Suspense' , 'div' , 'App' ] ) ,
629
+ ] ,
630
+ ] ,
631
+ [
632
+ [
633
+ 'The server could not finish this Suspense boundary, likely due to an error during server rendering. Switched to client rendering.' ,
634
+ expectedHash ,
635
+ ] ,
636
636
] ,
637
637
) ;
638
638
@@ -675,8 +675,8 @@ describe('ReactDOMFizzServer', () => {
675
675
loggedErrors . push ( x ) ;
676
676
return 'hash(' + x . message + ')' ;
677
677
}
678
- // const expectedHash = onError(theError);
679
- // loggedErrors.length = 0;
678
+ const expectedHash = onError ( theError ) ;
679
+ loggedErrors . length = 0 ;
680
680
681
681
await act ( async ( ) => {
682
682
const { pipe} = ReactDOMFizzServer . renderToPipeableStream (
@@ -693,8 +693,8 @@ describe('ReactDOMFizzServer', () => {
693
693
const errors = [ ] ;
694
694
// Attempt to hydrate the content.
695
695
ReactDOMClient . hydrateRoot ( container , < App isClient = { true } /> , {
696
- onRecoverableError ( error ) {
697
- errors . push ( error ) ;
696
+ onRecoverableError ( error , errorInfo ) {
697
+ errors . push ( { error, errorInfo } ) ;
698
698
} ,
699
699
} ) ;
700
700
Scheduler . unstable_flushAll ( ) ;
@@ -703,9 +703,18 @@ describe('ReactDOMFizzServer', () => {
703
703
704
704
expectErrors (
705
705
errors ,
706
- [ theError . message ] ,
707
706
[
708
- 'The server could not finish this Suspense boundary, likely due to an error during server rendering. Switched to client rendering.' ,
707
+ [
708
+ theError . message ,
709
+ expectedHash ,
710
+ componentStack ( [ 'Erroring' , 'Suspense' , 'div' , 'App' ] ) ,
711
+ ] ,
712
+ ] ,
713
+ [
714
+ [
715
+ 'The server could not finish this Suspense boundary, likely due to an error during server rendering. Switched to client rendering.' ,
716
+ expectedHash ,
717
+ ] ,
709
718
] ,
710
719
) ;
711
720
} ) ;
@@ -735,8 +744,8 @@ describe('ReactDOMFizzServer', () => {
735
744
loggedErrors . push ( x ) ;
736
745
return 'hash(' + x . message + ')' ;
737
746
}
738
- // const expectedHash = onError(theError);
739
- // loggedErrors.length = 0;
747
+ const expectedHash = onError ( theError ) ;
748
+ loggedErrors . length = 0 ;
740
749
741
750
await act ( async ( ) => {
742
751
const { pipe} = ReactDOMFizzServer . renderToPipeableStream (
@@ -753,8 +762,8 @@ describe('ReactDOMFizzServer', () => {
753
762
const errors = [ ] ;
754
763
// Attempt to hydrate the content.
755
764
ReactDOMClient . hydrateRoot ( container , < App isClient = { true } /> , {
756
- onRecoverableError ( error ) {
757
- errors . push ( error ) ;
765
+ onRecoverableError ( error , errorInfo ) {
766
+ errors . push ( { error, errorInfo } ) ;
758
767
} ,
759
768
} ) ;
760
769
Scheduler . unstable_flushAll ( ) ;
@@ -773,9 +782,18 @@ describe('ReactDOMFizzServer', () => {
773
782
774
783
expectErrors (
775
784
errors ,
776
- [ theError . message ] ,
777
785
[
778
- 'The server could not finish this Suspense boundary, likely due to an error during server rendering. Switched to client rendering.' ,
786
+ [
787
+ theError . message ,
788
+ expectedHash ,
789
+ componentStack ( [ 'Lazy' , 'Suspense' , 'div' , 'App' ] ) ,
790
+ ] ,
791
+ ] ,
792
+ [
793
+ [
794
+ 'The server could not finish this Suspense boundary, likely due to an error during server rendering. Switched to client rendering.' ,
795
+ expectedHash ,
796
+ ] ,
779
797
] ,
780
798
) ;
781
799
@@ -1053,9 +1071,10 @@ describe('ReactDOMFizzServer', () => {
1053
1071
}
1054
1072
1055
1073
const loggedErrors = [ ] ;
1074
+ const expectedHash = 'Hash for Abort' ;
1056
1075
function onError ( error ) {
1057
1076
loggedErrors . push ( error ) ;
1058
- return `Hash of ( ${ error . message } )` ;
1077
+ return expectedHash ;
1059
1078
}
1060
1079
1061
1080
let controls ;
@@ -1069,8 +1088,8 @@ describe('ReactDOMFizzServer', () => {
1069
1088
const errors = [ ] ;
1070
1089
// Attempt to hydrate the content.
1071
1090
ReactDOMClient . hydrateRoot ( container , < App /> , {
1072
- onRecoverableError ( error ) {
1073
- errors . push ( error ) ;
1091
+ onRecoverableError ( error , errorInfo ) {
1092
+ errors . push ( { error, errorInfo } ) ;
1074
1093
} ,
1075
1094
} ) ;
1076
1095
Scheduler . unstable_flushAll ( ) ;
@@ -1087,9 +1106,12 @@ describe('ReactDOMFizzServer', () => {
1087
1106
expect ( Scheduler ) . toFlushAndYield ( [ ] ) ;
1088
1107
expectErrors (
1089
1108
errors ,
1090
- [ 'This Suspense boundary was aborted by the server' ] ,
1109
+ [ [ 'This Suspense boundary was aborted by the server' , expectedHash ] ] ,
1091
1110
[
1092
- 'The server could not finish this Suspense boundary, likely due to an error during server rendering. Switched to client rendering.' ,
1111
+ [
1112
+ 'The server could not finish this Suspense boundary, likely due to an error during server rendering. Switched to client rendering.' ,
1113
+ expectedHash ,
1114
+ ] ,
1093
1115
] ,
1094
1116
) ;
1095
1117
expect ( getVisibleChildren ( container ) ) . toEqual ( < div > Loading...</ div > ) ;
@@ -1755,8 +1777,8 @@ describe('ReactDOMFizzServer', () => {
1755
1777
loggedErrors . push ( x ) ;
1756
1778
return `hash of (${ x . message } )` ;
1757
1779
}
1758
- // const expectedHash = onError(theError);
1759
- // loggedErrors.length = 0;
1780
+ const expectedHash = onError ( theError ) ;
1781
+ loggedErrors . length = 0 ;
1760
1782
1761
1783
let controls ;
1762
1784
await act ( async ( ) => {
@@ -1775,8 +1797,8 @@ describe('ReactDOMFizzServer', () => {
1775
1797
const errors = [ ] ;
1776
1798
// Attempt to hydrate the content.
1777
1799
ReactDOMClient . hydrateRoot ( container , < App isClient = { true } /> , {
1778
- onRecoverableError ( error ) {
1779
- errors . push ( error ) ;
1800
+ onRecoverableError ( error , errorInfo ) {
1801
+ errors . push ( { error, errorInfo } ) ;
1780
1802
} ,
1781
1803
} ) ;
1782
1804
Scheduler . unstable_flushAll ( ) ;
@@ -1809,9 +1831,25 @@ describe('ReactDOMFizzServer', () => {
1809
1831
expect ( Scheduler ) . toFlushAndYield ( [ ] ) ;
1810
1832
expectErrors (
1811
1833
errors ,
1812
- [ theError . message ] ,
1813
1834
[
1814
- 'The server could not finish this Suspense boundary, likely due to an error during server rendering. Switched to client rendering.' ,
1835
+ [
1836
+ theError . message ,
1837
+ expectedHash ,
1838
+ componentStack ( [
1839
+ 'AsyncText' ,
1840
+ 'h1' ,
1841
+ 'Suspense' ,
1842
+ 'div' ,
1843
+ 'Suspense' ,
1844
+ 'App' ,
1845
+ ] ) ,
1846
+ ] ,
1847
+ ] ,
1848
+ [
1849
+ [
1850
+ 'The server could not finish this Suspense boundary, likely due to an error during server rendering. Switched to client rendering.' ,
1851
+ expectedHash ,
1852
+ ] ,
1815
1853
] ,
1816
1854
) ;
1817
1855
@@ -3142,8 +3180,8 @@ describe('ReactDOMFizzServer', () => {
3142
3180
loggedErrors . push ( x ) ;
3143
3181
return x . message . replace ( 'bad message' , 'bad hash' ) ;
3144
3182
}
3145
- // const expectedHash = onError(theError);
3146
- // loggedErrors.length = 0;
3183
+ const expectedHash = onError ( theError ) ;
3184
+ loggedErrors . length = 0 ;
3147
3185
3148
3186
await act ( async ( ) => {
3149
3187
const { pipe} = ReactDOMFizzServer . renderToPipeableStream ( < App /> , {
@@ -3156,18 +3194,27 @@ describe('ReactDOMFizzServer', () => {
3156
3194
3157
3195
const errors = [ ] ;
3158
3196
ReactDOMClient . hydrateRoot ( container , < App isClient = { true } /> , {
3159
- onRecoverableError ( error ) {
3160
- errors . push ( error ) ;
3197
+ onRecoverableError ( error , errorInfo ) {
3198
+ errors . push ( { error, errorInfo } ) ;
3161
3199
} ,
3162
3200
} ) ;
3163
3201
expect ( Scheduler ) . toFlushAndYield ( [ ] ) ;
3164
3202
3165
3203
// If escaping were not done we would get a message that says "bad hash"
3166
3204
expectErrors (
3167
3205
errors ,
3168
- [ theError . message ] ,
3169
3206
[
3170
- 'The server could not finish this Suspense boundary, likely due to an error during server rendering. Switched to client rendering.' ,
3207
+ [
3208
+ theError . message ,
3209
+ expectedHash ,
3210
+ componentStack ( [ 'Erroring' , 'Suspense' , 'div' , 'App' ] ) ,
3211
+ ] ,
3212
+ ] ,
3213
+ [
3214
+ [
3215
+ 'The server could not finish this Suspense boundary, likely due to an error during server rendering. Switched to client rendering.' ,
3216
+ expectedHash ,
3217
+ ] ,
3171
3218
] ,
3172
3219
) ;
3173
3220
} ) ;
0 commit comments