[2.0 / next] <Errored> stays on its fallback after navigating away when a <Show>/<Match> condition read the failed fetch
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
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- 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.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của solidjs/solid
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 35/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 55/100
Maintainer thường phản hồi trong vòng 1 ngày
-
[2.0 / next] Optimistic todo list with an "N left" memo loops forever when a toggle's save landsĐang mở
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 15/100
Maintainer thường phản hồi trong vòng 1 ngày
-
[2.0 / next] createOptimisticStore: add, delete, add with saves pending hands <For> an undefined rowĐang mở
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 25/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 18/100
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của solidjs/solid
Issue tương tự
-
mobile-app
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 74/100
Open-Locker/Open-Locker#352 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 62/100
leanprover-community/lean4game#589 ·
Maintainer thường phản hồi trong vòng 2 ngày
-
Add: CS Action BGĐang mởcheck:passed streams:add
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 68/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 82/100
unocss/unocss#5421 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày