[2.0 / next] An <Errored> recovering after a retry waits for async under a nested <Loading>

已关闭
#4,425 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

还没有人认领这个 Issue。

评估

难度
4/5
预计耗时
1-2 天
新手友好度
52/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
活跃
领域
frontend, testing

调研方向

The report names a reproduction test under packages/web/test but no existing test file or implementation entry point. Start by locating the Errored recovery logic and related tests, then add the supplied nested Loading reproduction and run it. Done means recovered content shows immediately after the detail request succeeds, while the nested fallback remains until search results arrive.

由索引模型根据 Issue 内容生成。

描述

Found by: the ReactiveScript eval, at next 5e68925c (rc.20). The .rx and Solid TSX apps of one eval task now fail "retry after not found shows the issue". The same apps passed at 6b792a95. The likely cause is the Errored recovery change in #4406 (#4403 to #4405), but I haven't bisected.

Program

  • detail: an async memo that throws when the answer is null.
  • The view: <Loading> › <Errored> › <h2>{detail().title}</h2>, plus a child component that searches by the title, with its own <Loading> around the hits.

Steps

  1. detail answers null, so the fallback shows.
  2. refresh(detail).
  3. detail answers { title: "Crash" }.
  4. The nested search answers.

Text after each step

step nested search no nested search
not found err not found err not found
retry err not found err not found
retry landed err not found Crash
search landed Crashab —

Expected at "retry landed": Crashfinding. The recovered content shows, and the nested <Loading> shows its own fallback until the search answers. That nested boundary exists so its content doesn't hold the rest. Instead, the Errored keeps showing the old failure until the nested async lands. If that async is slow or never answers, the retry looks like it did nothing.

Test (packages/web/test)

/**
 * @jsxImportSource @solidjs/web
 * @vitest-environment jsdom
 */
import { test } from "vitest";
import { Errored, For, Loading, Show, createMemo, flush, refresh } from "solid-js";
import { render } from "../src/index.js";
const tick = async () => { for (let i = 0; i < 4; i++) { await new Promise(r => setTimeout(r, 0)); flush(); } };
for (const nested of [true, false])
test(`nested=${nested}`, async () => {
  const asks: { key: string; res: (v: any) => void }[] = [];
  const ask = (key: string) => new Promise<any>(res => asks.push({ key, res }));
  const land = async (key: string, v: any) => { const i = asks.findIndex(a => a.key === key); if (i < 0) throw new Error(`not asked ${key}: ${asks.map(a => a.key)}`); asks.splice(i, 1)[0].res(v); await tick(); };
  const container = document.body.appendChild(document.createElement("div"));
  const frames: string[] = [];
  const snap = (tag: string) => frames.push(`${tag.padEnd(14)} ${container.textContent}`);
  let detail!: () => any;
  function Related(props: { title: string }) {
    const hits = createMemo(() => ask(`search:${props.title}`));
    return <Loading fallback={<i>finding</i>}><For each={hits()}>{(h: any) => <i>{h}</i>}</For></Loading>;
  }
  render(() => {
    detail = createMemo(async () => { const d = await ask("detail"); if (!d) throw new Error("not found"); return d; });
    return (
      <Loading fallback={<p>loading</p>}>
        <Errored fallback={(e: any) => <p>err {e().message}</p>}>
          <h2>{detail().title}</h2>
          {nested && <Show when={detail()}>{(d: any) => <Related title={d().title} />}</Show>}
        </Errored>
      </Loading>
    );
  }, container);
  await tick();
  await land("detail", null); snap("not found");
  refresh(detail); flush(); await tick(); snap("retry");
  await land("detail", { title: "Crash" }); snap("retry landed");
  if (nested) { await land("search:Crash", ["a", "b"]); snap("search landed"); }
  console.log(`nested=${nested}\n  ` + frames.join("\n  "));
  container.remove();
});
主要语言
TypeScript
星标
36.2k
派生
1.1k
平均合并
11 小时 5 分钟
30 天内合并 PR
475

环境准备

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

solidjs/solid 的其他 Issue

查看 solidjs/solid 的全部 Issue

相似的 Issue

更多 TypeScript Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。