@@ -1045,14 +1045,40 @@ function pushAdditionalFormField(
10451045
10461046function pushAdditionalFormFields (
10471047 target : Array < Chunk | PrecomputedChunk > ,
1048- formData : null | FormData ,
1048+ formData : void | null | FormData ,
10491049) {
1050- if ( formData !== null ) {
1050+ if ( formData != null ) {
10511051 // $FlowFixMe[prop-missing]: FormData has forEach.
10521052 formData . forEach ( pushAdditionalFormField , target ) ;
10531053 }
10541054}
10551055
1056+ function getCustomFormFields (
1057+ resumableState : ResumableState ,
1058+ formAction : any ,
1059+ ) : null | ReactCustomFormAction {
1060+ const customAction = formAction . $$FORM_ACTION ;
1061+ if ( typeof customAction === 'function' ) {
1062+ const prefix = makeFormFieldPrefix ( resumableState ) ;
1063+ try {
1064+ return formAction . $$FORM_ACTION ( prefix ) ;
1065+ } catch ( x ) {
1066+ if ( typeof x === 'object' && x !== null && typeof x . then === 'function' ) {
1067+ // Rethrow suspense.
1068+ throw x ;
1069+ }
1070+ // If we fail to encode the form action for progressive enhancement for some reason,
1071+ // fallback to trying replaying on the client instead of failing the page. It might
1072+ // work there.
1073+ if ( __DEV__ ) {
1074+ // TODO: Should this be some kind of recoverable error?
1075+ // console.error('Failed to serialize an action for progressive enhancement:\n', x);
1076+ }
1077+ }
1078+ }
1079+ return null ;
1080+ }
1081+
10561082function pushFormActionAttribute (
10571083 target : Array < Chunk | PrecomputedChunk > ,
10581084 resumableState : ResumableState ,
@@ -1062,7 +1088,7 @@ function pushFormActionAttribute(
10621088 formMethod : any ,
10631089 formTarget : any ,
10641090 name : any ,
1065- ) : null | FormData {
1091+ ) : void | null | FormData {
10661092 let formData = null ;
10671093 if ( enableFormActions && typeof formAction === 'function' ) {
10681094 // Function form actions cannot control the form properties
@@ -1092,12 +1118,10 @@ function pushFormActionAttribute(
10921118 ) ;
10931119 }
10941120 }
1095- const customAction : ReactCustomFormAction = formAction . $$FORM_ACTION ;
1096- if ( typeof customAction === 'function' ) {
1121+ const customFields = getCustomFormFields ( resumableState , formAction ) ;
1122+ if ( customFields !== null ) {
10971123 // This action has a custom progressive enhancement form that can submit the form
10981124 // back to the server if it's invoked before hydration. Such as a Server Action.
1099- const prefix = makeFormFieldPrefix ( resumableState ) ;
1100- const customFields = formAction . $$FORM_ACTION ( prefix ) ;
11011125 name = customFields . name ;
11021126 formAction = customFields . action || '' ;
11031127 formEncType = customFields . encType ;
@@ -1882,12 +1906,10 @@ function pushStartForm(
18821906 ) ;
18831907 }
18841908 }
1885- const customAction : ReactCustomFormAction = formAction . $$FORM_ACTION ;
1886- if ( typeof customAction === 'function' ) {
1909+ const customFields = getCustomFormFields ( resumableState , formAction ) ;
1910+ if ( customFields !== null ) {
18871911 // This action has a custom progressive enhancement form that can submit the form
18881912 // back to the server if it's invoked before hydration. Such as a Server Action.
1889- const prefix = makeFormFieldPrefix ( resumableState ) ;
1890- const customFields = formAction . $$FORM_ACTION ( prefix ) ;
18911913 formAction = customFields . action || '' ;
18921914 formEncType = customFields . encType ;
18931915 formMethod = customFields . method ;
0 commit comments