solid-start icon indicating copy to clipboard operation
solid-start copied to clipboard

[Bug?]: internal $fetch (Nitro) looping endlessly in build pre-rendering since 1.0.7

Open Jylth opened this issue 1 year ago • 2 comments

Duplicates

  • [X] I have searched the existing issues

Latest version

  • [X] I have tested the latest version

Current behavior 😯

Since 1.0.7, in a setup where we have internal API routes, and we're trying to fetch them in the nitro build through the $fetch helper, the page is rendering endlessly in a stuck loop.

https://nitro.unjs.io/guide/fetch#in-server-fetch.

Downgrading @solidjs/start to 1.0.6 fixes the issue.

Expected behavior 🤔

Same behaviour as 1.0.6, which doesn't break internal api calls through the $fetch event helper.

Steps to reproduce 🕹

Steps:

  1. Go to https://stackblitz.com/~/github.com/Jylth/solid_issue_prerender_fetch_internal_api?file=src/routes/index.tsx
  2. Run a build with pnpm build
  3. Observe that the page prerendering of the index is looping endlessly

To fix the issue, simply downgrade the @solidjs/start package to 1.0.6.

Context 🔦

This breaks an app which was working well since a couple of months on v1.0.6. Upgrading to a more recent version of the package breaks it completely.

The behaviour on a more complex app is a bit different. Instead of looping endlessly, the nitro server simply stops after trying prerendering the route and the build fails. Logging the requests in a middleware shows that the internal API calls are received, but the path of the request is missing, they all go to the root /.

Might be the same issue as #1640

Jylth avatar Oct 09 '24 19:10 Jylth

Oh interesting.. I didn't know $fetch existed. And since Vinxi doesn't use Nitro in Dev I'm a little surprised it ever worked. I have to admit I have no idea what would have changed in 1.0.7 other than updating the Vinxi version. So we might need to track back through those changes.

ryansolid avatar Oct 09 '24 20:10 ryansolid

Yeah indeed, in our app, the $fetch in development is mocked and replaced by the native fetch via a middleware.

But It does work very well in production, using cloudflare workers.

I was also suspecting vinxi, but forcing the resolution of Vinxi to the same version as the one used in solid-start 1.0.6 ([email protected]) does not fix the issue.

Jylth avatar Oct 09 '24 20:10 Jylth

Hmm.. it's just that 1.0.7 vs 1.0.6 had very minimal changes on our side. The only thing I can think that could be related is: https://github.com/solidjs/solid-start/pull/1586.

Other than changing to support encoded URLs in the API router nothing else changed Start's build. We did update Vinxi from 0.4.1 to 0.4.3 though.

ryansolid avatar Oct 31 '24 21:10 ryansolid

I managed to upgrade our app to the latest solid-start version. I did need to update the usage of $fetch: We went from simply calling $fetch like this, which still caused the infinite loop:

event.nativeEvent.$fetch('/some-route/nested')

to calling it like this:

event.nativeEvent.$fetch('/some-route/nested', {
   context: {...} 
   // pass your context here, eg
   // { cloudflare: event.nativeEvent.context.cloudflare }
})

Simply passing a context object to the call fixed the issue. Do not pass the full context from the current event to it, otherwise nitro seems to skip recreating an event and we're re-using the same event which causes all sort of issues likes the event.request.url to not use the given internal path.

I found that out by digging deeper into how nitro was implementing its internal fetch behavior through $fetch https://github.com/nitrojs/nitro/blob/cba49a377b56468ba0577cc1db54654f58f14a0e/src/runtime/internal/app.ts And this is the package which creates the internal fetcher: https://github.com/unjs/node-mock-http/blob/main/src/fetch/call.ts

Jylth avatar Mar 04 '25 17:03 Jylth