Skip to content

fix: handle rejected module promises in lazy() - #2955

Open
birkskyum wants to merge 1 commit into
solidjs:mainfrom
birkskyum:fix-renderToStream
Open

fix: handle rejected module promises in lazy()#2955
birkskyum wants to merge 1 commit into
solidjs:mainfrom
birkskyum:fix-renderToStream

Conversation

@birkskyum

@birkskyum birkskyum commented Jul 28, 2026

Copy link
Copy Markdown
Member

On the server lazy() attached only a success handler to the module promise. When the promise rejected, the Suspense boundary's _loading flag was never cleared, so notifySuspense never fired, the registered fragment never resolved and renderToStream never called end(): the response hung open and the error never reached an enclosing ErrorBoundary. Without a host unhandledRejection handler the un-caught .then in load crashed the process instead.

The rejection is now recorded next to the resolved module, the boundary is notified so the fragment resolves, and the error is thrown where the component renders so ErrorBoundary can catch it.

The client's hydration branch had the same success-only handler, leaving sharedConfig.count pinned and swallowing the error. It now decrements the count and surfaces the rejection to the nearest ErrorBoundary.

SSR had no test harness, so this adds a second vitest project that resolves solid-js to the server entries.

On the server `lazy()` attached only a success handler to the module
promise. When the promise rejected, the Suspense boundary's `_loading`
flag was never cleared, so `notifySuspense` never fired, the registered
fragment never resolved and `renderToStream` never called `end()`: the
response hung open and the error never reached an enclosing
`ErrorBoundary`. Without a host `unhandledRejection` handler the
un-caught `.then` in `load` crashed the process instead.

The rejection is now recorded next to the resolved module, the boundary
is notified so the fragment resolves, and the error is thrown where the
component renders so `ErrorBoundary` can catch it.

The client's hydration branch had the same success-only handler, leaving
`sharedConfig.count` pinned and swallowing the error. It now decrements
the count and surfaces the rejection to the nearest `ErrorBoundary`.

SSR had no test harness, so this adds a second vitest project that
resolves `solid-js` to the server entries.

Closes solidjs#2945
@changeset-bot

changeset-bot Bot commented Jul 28, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: cc9a3a6

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
solid-js Patch
test-integration Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[solid v1] renderToStream() never closes when a lazy() component's module promise rejects

1 participant