@@ -39,6 +39,7 @@ export async function handleRequest({
3939 let returnValue : RscPayload [ 'returnValue' ] | undefined
4040 let formState : ReactFormState | undefined
4141 let temporaryReferences : unknown | undefined
42+ let actionStatus : number | undefined
4243 if ( isAction ) {
4344 // x-rsc-action header exists when action is called via `ReactClient.setServerCallback`.
4445 const actionId = request . headers . get ( 'x-rsc-action' )
@@ -55,15 +56,24 @@ export async function handleRequest({
5556 returnValue = { ok : true , data }
5657 } catch ( e ) {
5758 returnValue = { ok : false , data : e }
59+ actionStatus = 500
5860 }
5961 } else {
6062 // otherwise server function is called via `<form action={...}>`
6163 // before hydration (e.g. when javascript is disabled).
6264 // aka progressive enhancement.
6365 const formData = await request . formData ( )
6466 const decodedAction = await decodeAction ( formData )
65- const result = await decodedAction ( )
66- formState = await decodeFormState ( result , formData )
67+ try {
68+ const result = await decodedAction ( )
69+ formState = await decodeFormState ( result , formData )
70+ } catch ( e ) {
71+ // there's no single general obvious way to surface this error,
72+ // so explicitly return classic 500 response.
73+ return new Response ( 'Internal Server Error: server action failed' , {
74+ status : 500 ,
75+ } )
76+ }
6777 }
6878 }
6979
@@ -82,7 +92,7 @@ export async function handleRequest({
8292
8393 if ( isRscRequest ) {
8494 return new Response ( rscStream , {
85- status : returnValue ?. ok === false ? 500 : undefined ,
95+ status : actionStatus ,
8696 headers : {
8797 'content-type' : 'text/x-component;charset=utf-8' ,
8898 vary : 'accept' ,
@@ -97,15 +107,16 @@ export async function handleRequest({
97107 const ssrEntryModule = await import . meta. viteRsc . loadModule <
98108 typeof import ( './entry.ssr.tsx' )
99109 > ( 'ssr' , 'index' )
100- const htmlStream = await ssrEntryModule . renderHTML ( rscStream , {
110+ const ssrResult = await ssrEntryModule . renderHTML ( rscStream , {
101111 formState,
102112 nonce,
103113 // allow quick simulation of javscript disabled browser
104114 debugNojs : url . searchParams . has ( '__nojs' ) ,
105115 } )
106116
107117 // respond html
108- return new Response ( htmlStream , {
118+ return new Response ( ssrResult . stream , {
119+ status : ssrResult . status ,
109120 headers : {
110121 'content-type' : 'text/html;charset=utf-8' ,
111122 vary : 'accept' ,
0 commit comments