[Bug?]: createResource fails if using SSR and an exception is thrown in the wrapped function
Duplicates
- [X] I have searched the existing issues
Latest version
- [X] I have tested the latest version
Current behavior 😯
Using createResource after Solid Start 1.0 fails if ssr: true and an exception is thrown in the resource. The error does not come back in myResource.error nor does the resource state transition correctly, and the error boundary is hit instead. This breaks code with no work arounds other than changing all code to return error values instead of exceptions.
See note: https://discord.com/channels/722131463138705510/910635844119982080/1245249872156954708
and stackblitz: https://stackblitz.com/edit/github-hzq3du-1rmrvf?file=src%2Froutes%2Findex.tsx
Expected behavior 🤔
The exception thrown inside createResource shows in the resource error property and not hitting the error boundary.
Steps to reproduce 🕹
Steps:
- add a createResource in a component that throws an exception
- put error boundary in the component
- use the results and error state of the resource in the JSX
- log in an effect the state transition, result, and error state of the effect
note that the logging and value under error state are incorrect and error boundary is hit instead.
Context 🔦
Normal behavior that worked and is documented but now does not work.
Your environment 🌎
Solid-Start 1.0.0
Solid 1.8.17
This behavior for createResource seems correct. We always throw on read (and always have, the .error property was added later). You can guard the read with the .error property but reading the resource itself directly throws. So if the resource read was in the fallback or vice versa it would not get caught in the ErrorBoundary.
The resource goes into the wrong state regardless and ends up as state ready on the error with the result and error field undefined This is the wrong state. Only happens via SSR=true
I don't think resources handle failed serialized promises correctly, p.value isn't passed to the third argument of loadEnd anywhere.
if ("value" in p) {
if ((p as any).status === "success") loadEnd(pr, p.value as T, undefined, lookup);
else loadEnd(pr, undefined, undefined, lookup);
return p;
}
I've opened a PR to Solid to add a status === "failure" branch, which makes the repro behave correctly - the resource's status logs "errored" instead of "ready".
This should be fixed in Solid 1.8.18