Invoking redirecting action can cause runtime client error due to type mismatch #63771
Labels
bug
Issue was opened via the bug report template.
linear: next
Confirmed issue that is tracked by the Next.js team.
Link to the code that reproduces this issue
https://github.com/juliusmarminge/next-redirect-action-bug
To Reproduce
Sandbox: https://stackblitz.com/edit/stackblitz-starters-ajhapq?file=app%2FGoToGoogle.tsx
CleanShot.2024-03-27.at.16.02.27.mp4
Current vs. Expected behavior
Due to the current architecture of
redirect
throwing in server actions, the type is (accurately)never
, signaling that no code after theredirect()
will execute. This is great and provides a great developer experience when making actions. However, it comes with a footgun that I think has been overlooked during the API design phase.When a function returns
never
, we expect the function not to return, and thus code below wont get executed. While this is the case within the action, it is not the case at the place where the action is invoked. When invoking the action, the function does not throw but instead returnsundefined
before eventually the browser navigates to the redirected URL.In the sandbox above, we conditionally return an envelope (
{ ok: false, message: string }
, and since the other branch of the action throws, the entire functions return type is just the envelope. On the client, we now get a type mismatch since invoking the action can return{ ok: false, message: string } | undefined
but the undefined part is not in the type. This will very likely be overlooked by users and thus cause runtime errors (as seen in the demo). I'd expect the return type to be a union with the undefined part so we can get TypeScript assistance in checking for this condition to avoid these errors.With the current architecture, this is indeed not possible. My suggestion would be to
<Image />
component for example)Here is how actions would be written in this new way:
The redirect function would return some symbol-like thing that can be identified when the action is executed and trigger the redirect behavior similar to today. For reference, see trpc/trpc#5593
Some pseudo code:
Of course this comes with a new mismatch that it returns an error but the type says undefined, but I think that's way less dangerous and also don't see why one would const variable = redirect(url).
Provide environment information
Which area(s) are affected? (Select all that apply)
App Router
Which stage(s) are affected? (Select all that apply)
next dev (local), next start (local)
Additional context
Don't know why #63770 got closed, are sandboxes not valid reproductions??
NEXT-3299
The text was updated successfully, but these errors were encountered: