bugfix: actions that redirect should reject the action promise (#69945)
When calling `redirect` in a server action, the action handler will
invoke a worker to fetch the RSC payload from the URL being redirected
to, and will return it in the action request. This allows the redirect
to be handled in a single request rather than requiring a second request
to fetch the RSC payload on the URL being redirected to. As part of this
special redirection handling, no action result is returned, so the
action promise is resolved with `undefined`.
As a result of this behavior, if your server action redirects to a page
that has the same form that was just submitted, and you're leveraging
`useActionState`, the updated state value will be undefined rather than
being reset to the initial state. **More generally, redirect errors are
handled by the client currently by simply resolving the promise with
undefined, which isn't the correct behavior.**
This PR will reject the server action promise with a redirect error, so
that it'll be caught by our `RedirectBoundary`. Since React will remount
the tree as part of the error boundary recovery, this effectively resets
the form to it's initial state.
If the action is rejected in a global `startTransition`, then it'll be
handled by a global `error` handler, which will perform the redirect.
And if it occurs outside of a transition, the redirect will be handled
by a `unhandledrejection` handler.
Because we're not able to apply the flight data as-is in the server
action reducer (and instead defer to the navigation action), we seed the
prefetch cache for the target page with the flight data from the action
result so that we do not need to make another server roundtrip. We apply
the same static/dynamic cache staleTime heuristics for these cache
entries.
Fixes #68549
Closes NDX-229