Skip to content

fix(signals): settle deferred flights after protocol throws - #4248

Merged
ryansolid merged 1 commit into
solidjs:nextfrom
GabbeV:fix/deferred-protocol-flight
Oct 24, 2026
Merged

ryansolid merged 1 commit into
solidjs:nextfrom
GabbeV:fix/deferred-protocol-flight

Conversation

@GabbeV

@GabbeV GabbeV commented Oct 23, 2026

Copy link
Copy Markdown

Summary

After createDeferred has answered, a synchronous throw from an iterator's first next() leaves its flight pending: isPending stays true and until/refresh never receive the error. A throwing iterator factory can similarly leave the current error waiting for an obsolete request to settle.

Extend the existing computation try/catch through result processing, including iterator setup and the initial pull. Preserve its error policy: an unready reactive source parks the flight on its NotReadyError; other errors retire the flight and are rethrown unchanged. This adds no wrapper, allocation, or extra catch block. Includes 26 regression/control cases and a patch changeset.

This follows up #4231's fix for computation-body throws. Related #4112 / #4158 fixed protocol exceptions escaping ordinary memo error handling; this addresses createDeferred's additional flight bookkeeping.

Minimal JSX playground, pinned to 2.0.0-rc.18. Click Run once. Expected: Pending: false, followed by the stream failed error. Actual: Pending: true, and the error never reaches the awaiting caller. Changing only next() to async next() is a passing control. The saved share was reopened and both cases checked. The same component reproduces against unchanged source-built next@cc3ee740 and passes with the fix in production, development and observe builds.

How did you test this change?

  • On unchanged cc3ee740, 13 new cases fail and 13 controls pass. All 26 pass with the fix, as do all 100 focused tests, covering until/refresh, loading seeds, obsolete flights and unready-source parking.
  • Signals JavaScript builds for all three tiers and source declarations pass (npm run build:js, npm run types). Full signals suite: 342 files / 5,573 tests pass, with two expected failures and two skips (vitest run --maxWorkers=2).
  • All 120 native repro/control cases and six actual JSX browser cases pass with the fix across production, development and observe builds.
  • Prettier checks on all three changed files and node scripts/check-release-invariants.mjs pass.
  • Rolldown 1.2.11: the four standard signals size scenarios are unchanged and their comparison gates pass. A focused createDeferred import is 1 minified byte / 15 Brotli bytes smaller. No caps changed.
  • A separate TypeScript check of the signals test tree reports the same 30 existing diagnostics on base and candidate, with no new diagnostics.

@changeset-bot

changeset-bot Bot commented Oct 23, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 58d3d52

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

This PR includes changesets to release 14 packages
Name Type
@solidjs/signals Patch
test-integration Patch
@solidjs/web Patch
@solidjs/babel-plugin Patch
@solidjs/compiler Patch
@solidjs/diagnostics Patch
@solidjs/element Patch
@solidjs/h Patch
@solidjs/html Patch
solid-js Patch
@solidjs/universal Patch
board-example Patch
server-dbmon-example Patch
todos-server-example 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

@codspeed

codspeed Bot commented Oct 23, 2026

Copy link
Copy Markdown

Merging this PR will improve performance by 10.2%

2 warnings

⚠️ 2 benchmarks are dominated by system calls

System calls cannot be simulated consistently and are left out of the measure. The reported value understates the real cost. Switch to the Walltime instrument to measure them.

Learn more about system calls

See affected benchmarks

⚠️ Base and head ran on different runner types

Some benchmarks with significant performance changes were compared across different runner types, so the changes might not come from the code. Run base and head on the same runner type, or use CodSpeed Macro Runners for more stable results.

Learn more about Macro Runners

Open the report in CodSpeed to investigate

⚡ 1 improved benchmark
✅ 195 untouched benchmarks
⏩ 5 skipped benchmarks1

Performance Changes

Benchmark BASE HEAD Efficiency
⚡ memo + sync render effect only (reference) 31.6 ms 28.6 ms +10.2%

Tip

Curious why performance improved? Comment @codspeedbot explain why performance improved on this PR, or directly use the CodSpeed MCP with your agent.


Comparing GabbeV:fix/deferred-protocol-flight (58d3d52) with next (cc3ee74)

Open in CodSpeed

Footnotes

  1. 5 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

@ryansolid
ryansolid merged commit 0dd40b2 into solidjs:next Oct 24, 2026
8 checks passed
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.

2 participants