[2.0 / next] <Errored> stays on its fallback after navigating away when a <Show>/<Match> condition read the failed fetch

Đang mở
#4,644 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức phù hợp với người mới
35/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
typescript
Lĩnh vực
frontend

Hướng nghiên cứu

The failing spec is the vitest case built from the readers table in packages/web/test/, and the two control cases (text and For) pass, so start by comparing how the Show and Switch/Match readers consume the failed async memo. Run npx vitest run in packages/web to reproduce. Done means the Show and Switch/Match variants report about page after navigation while the controls still pass.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

Describe the bug

A list page reads an async memo, and the list fetch fails, so the <Errored> around the page shows its fallback. The user then navigates to another page, which is a different branch under the same <Errored>. If the list page read the failed memo in a <Show when> or a <Match when>, for example the usual empty-state check <Show when={rows().length === 0}>, the boundary keeps showing its fallback after the navigation, and the app stays on the error until a reload.

A plain read of the same memo (text, <For>, <Repeat>, an attribute, latest()) recovers on navigation. A wider sweep found the same failure for a memo of the condition used in a <Show>, for a keyed <Show>, and with or without a <Loading> around the page, and with the navigation done by <Show> or by <Switch>. Recovery by refresh() or by changing the memo's input works in every case.

Found by fuzzing reactivescript's example apps (a notes app whose list uses an empty-state <Show>), then reduced to plain Solid.

Your Example Website or App

The vitest spec below (in packages/web/test/), on next @ 42350195f.

Steps to Reproduce the Bug or Issue
import { render } from "@solidjs/web";
import { createMemo, createSignal, Errored, flush, For, Loading, Match, Show, Switch } from "solid-js";
import { expect, it } from "vitest";

const tick = async () => { for (let i = 0; i < 2; i++) { await new Promise(r => setTimeout(r, 0)); flush(); } };
type Row = { id: number };

const readers: Record<string, (rows: () => Row[]) => any> = {
  "Show when={rows().length === 0}": rows => <Show when={rows().length === 0} fallback={<p>{rows().length} rows</p>}><p>no rows</p></Show>,
  "Show when={rows()}": rows => <Show when={rows()}>{r => <p>{r().length} rows</p>}</Show>,
  "Switch/Match": rows => <Switch fallback={<p>{rows().length} rows</p>}><Match when={rows().length === 0}><p>no rows</p></Match></Switch>,
  "text (control)": rows => <p>{rows().length} rows</p>,
  "For (control)": rows => <ul><For each={rows()}>{r => <li>{r.id}</li>}</For></ul>,
};

for (const [name, view] of Object.entries(readers))
it(`${name}: navigating away from a failed list clears <Errored>`, async () => {
  let rejectList!: (e: Error) => void;
  const el = document.createElement("div");
  let setPage!: (p: string) => void;
  const dispose = render(() => {
    const [page, set] = createSignal("list"); setPage = set;
    const rows = createMemo(() => new Promise<Row[]>((_, reject) => { rejectList = reject; }));
    return (
      <Errored fallback={<p>could not load</p>}>
        <Show when={page() === "list"} fallback={<p>about page</p>}>
          <Loading fallback={<p>loading</p>}>{view(rows)}</Loading>
        </Show>
      </Errored>
    );
  }, el);
  await tick();
  rejectList(new Error("boom")); await tick();
  const failed = el.textContent;
  setPage("about"); flush(); await tick();
  const after = el.textContent;
  dispose();
  expect({ failed, after }).toEqual({ failed: "could not load", after: "about page" });
});

npx vitest run in packages/web. The two control tests pass; the Show and Switch/Match tests fail with after: "could not load".

Expected behavior

After navigating away, nothing under the boundary reads the failed memo, so <Errored> renders the new branch (about page), as it does when the list page reads the memo as text or in a <For>.

Platform
  • OS: macOS
  • Browser: n/a (jsdom)
  • Version: solid-js 2.0.0-rc.20, next @ 42350195f
Ngôn ngữ chính
TypeScript
Star
36.2k
Fork
1.1k
Merge trung bình
10 giờ 39 phút
Pull request đã merge (30 ngày)
500

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của solidjs/solid

Tất cả issue của solidjs/solid

Issue tương tự

Thêm issue về TypeScript

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.