Crash when server function throws redirect and wrapped in createAsync
Describe the bug
If you throw a redirect from a server function wrapped in createAsync it does not handle the redirect nor serialize it across. Server functions called as actions might want to throw redirects, and if used elsewhere it is likely they would as well. cache wrapping handles the redirect, but if you do not want caching, you do not have a noCache option and therefore throw or return a redirect causing what? currently a crash.
Example:
async function serverApiCallThrow(isIndirect?: boolean): Promise<string> {
'use server';
throw redirect(`/${isIndirect ? 'fromIndirect' : 'fromThrow'}/whateva?q=456`);
return 'ok'
}
...
const asyncThing = createAsync(()=>serverApiCallThrow())
...
<Show when={asyncThing()}>
<div>boo!</div>
</Show>
results in exception:
Error: Unknown error at castError (...server bundle...)
and client shows:
Your Example Website or App
see above
Steps to Reproduce the Bug or Issue
- create a server function
- throw a redirect in that functino
- use in a component with
createAsync - boom
Expected behavior
The redirect happens or thrown as error, but not a serialization crash
Screenshots or Videos
No response
Platform
any
Additional context
No response
From what I can tell this is already being thrown as a normal error and not a crash - wrapping the <Show> in an ErrorBoundary functions as you'd expect.
Perhaps just a better error message is necessary?
I think the issue here is that instead of handling the redirect, and navigating user to the new url, it throws an error. I don't think wrapping <Show> in ErrorBoundary will help.
From the docs it seems that only cache and action functions know how to correctly handle redirects. But I think there are cases, when we don't want to cache this function. For me it seems like missing functionality. We can try to use some workarounds, like cache revalidation, or pass some dummy random argument, so it will always produce unique cache key, but that doesn't seem as right thing to do.
Yeah cache and action are the only wrappers that handle redirects, it's possible that a third neutral one is needed.
Even then a thrown response in a raw server function surfacing as an error is still expected behaviour, it could just be reported better.
Wrapping the <Show> in ErrorBoundary doesn't help, but it functions as you'd expect any other error to (repo) rather than causing a crash which would be more worrying.
Just flagging here that I stumbled upon this problem as well. It'd be useful to have another more neutral way of sending redirects.
I was fetching some session data from the server and if it's not present I wanted to redirect to the sign in page. I ended up wrapping the function in an action but had to go through all the useAction / useSubmission overhead to be able to get the value. createAsync already returned a signal which is easier to handle.