[2.0 / next] A memo reading latest(a) beside b() computes a torn pass on a batched write; if that pass throws, the error sticks

クローズ
#4,365 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
4/5
見積もり時間
1〜2日
初心者へのやさしさ
48/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
活発
技術スタック
javascript, typescript
領域
frontend

調査の方向性

The reproduction is in packages/web/test/async-gen; begin by reading it and tracing how latest, createMemo, and batched writes interact in Solid’s reactive runtime. Add a regression test for the throwing memo and the torn tuple case, then verify that the memo reaches the fresh value after the batch and effects do not commit a mixed tuple. The issue does not name the runtime implementation file or an existing test command.

索引モデルが issue の本文から書いたものです。

説明

Found by the async app generator (packages/web/test/async-gen, branch claude/project-thread-bgafe5), minimized. There is no async anywhere in this case.

const [a, setA] = createSignal(1);
const [b, setB] = createSignal(0);
render(() => {
  const m = createMemo(() => {
    const v = latest(a) + b() + 1;
    if (v % 4 === 3) throw new Error("m:" + v);
    return v;
  });
  return <Errored fallback={e => `[E ${e()?.message}]`}><span title={String(m())} /></Errored>;
}, el);
flush();
setB(3); setA(2); flush();
// m computes latest(a)=2 with b()=0 → 3 → throws, and never re-runs: screen stays [E m:3]

Expected: m = 2 + 3 + 1 = 6, <span title="6">. A fresh render with a=2 and b=3 shows that.

Actual on next (1f558e50): the memo runs one pass with the new latest(a) beside the old b(). When that pass throws, the boundary keeps the error, and nothing re-runs m with b=3.

Without the throw, the torn pass still reaches effects. In a memo returning [latest(s), s()] after set(2), a render effect commits [2,1] before [2,2]. That is a torn tuple from a plain write with no transition held, which "latest tears" (#4284) doesn't seem to cover.

主要言語
TypeScript
スター
36.2k
フォーク
1.1k
平均マージ
11時間 5分
マージ済み PR(30日)
475

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

solidjs/solid のほかの issue

solidjs/solid の issue をすべて見る

似ている issue

TypeScript の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。