@@ -69,7 +69,7 @@ function parseQueryString(search: string): Array<string | undefined> {
6969}
7070
7171export default function ErrorDecoder ( ) {
72- const { errorMessage} = useErrorDecoderParams ( ) ;
72+ const { errorMessage, errorCode } = useErrorDecoderParams ( ) ;
7373 /** error messages that contain %s require reading location.search */
7474 const hasParams = errorMessage ?. includes ( '%s' ) ;
7575 const [ message , setMessage ] = useState < React . ReactNode | null > ( ( ) =>
@@ -82,23 +82,28 @@ export default function ErrorDecoder() {
8282 if ( errorMessage == null || ! hasParams ) {
8383 return ;
8484 }
85+ const args = parseQueryString ( window . location . search ) ;
86+ let message = errorMessage ;
87+ if ( errorCode === '418' ) {
88+ // Hydration errors have a %s for the diff, but we don't add that to the args for security reasons.
89+ message = message . replace ( / % s $ / , '' ) ;
8590
86- setMessage (
87- urlify (
88- replaceArgs (
89- errorMessage ,
90- parseQueryString ( window . location . search ) ,
91- '[missing argument]'
92- )
93- )
94- ) ;
91+ // Before React 19.1, the error message didn't have an arg, and was always HTML.
92+ if ( args . length === 0 ) {
93+ args . push ( 'HTML' ) ;
94+ } else if ( args . length === 1 && args [ 0 ] === '' ) {
95+ args [ 0 ] = 'HTML' ;
96+ }
97+ }
98+
99+ setMessage ( urlify ( replaceArgs ( message , args , '[missing argument]' ) ) ) ;
95100 setIsReady ( true ) ;
96- } , [ hasParams , errorMessage ] ) ;
101+ } , [ errorCode , hasParams , errorMessage ] ) ;
97102
98103 return (
99104 < code
100105 className = { cn (
101- 'block bg-red-100 text-red-600 py-4 px-6 mt-5 rounded-lg' ,
106+ 'whitespace-pre-line block bg-red-100 text-red-600 py-4 px-6 mt-5 rounded-lg' ,
102107 isReady ? 'opacity-100' : 'opacity-0'
103108 ) } >
104109 < b > { message } </ b >
0 commit comments