solidjs / solid-start

SolidStart, the Solid app framework
https://start.solidjs.com
MIT License
4.93k stars 371 forks source link

[Bug?]: createResource fails if using SSR and an exception is thrown in the wrapped function #1520

Open apatrida opened 1 month ago

apatrida commented 1 month ago

Duplicates

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:

  1. add a createResource in a component that throws an exception
  2. put error boundary in the component
  3. use the results and error state of the resource in the JSX
  4. 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
ryansolid commented 1 month ago

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.

apatrida commented 1 month ago

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

Brendonovich commented 2 weeks ago

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".