Repository navigation
Commit 2a0b37b
fix(console): a missing public /f/:slug form renders the shared localized not-found state (#27782)
domain:ui#4 · os-bill · session_01Utp6CbDAucNyQ4UtzCJKyh
<!-- claude-projects-attribution: {"github_login":"os-bill"} -->
_Requested by **Bill** · [project
thread](https://claude.ai/code/project/chan_016iMXWSZDzqWRWvWzdNo8wg?thread=cmsg_016iMXWSZDzqWRWvWzdNo8wgDFH4S5pR1C8YvYCWWsZfXx)_
Fixes #27756
Clause-②: no
Metadata-protocol: none
## 维护者速读
- 改了什么:访客打开一个不存在、未发布或已停用的公开表单链接 `/f/SLUG` 时,不再显示英文原文 "Failed to load
form (404):
服务端原文",改为显示控制台通用的「页面不存在」空状态(按会话语言显示,不带「返回」按钮);其它加载失败显示本地化的「表单加载失败」横幅,不再回显服务端正文。
- 为什么改:非英文会话的访客会看到一句未翻译的英文报错,且内容含服务端消息;内部 `/forms/NAME` 路由已在 #27446
改为本地化空状态,公开路由需一致。
- 风险与回滚:只动 `FormPage.tsx` 的公开表单加载与错误渲染;未新增或修改任何 i18n 键;内部路由行为不变。回滚即
revert 本 PR。
- 先看:`ui/apps/console/src/components/FormPage.tsx` 中 `loadPublicForm` 与
`PublicFormUnavailableError`、以及 `if (notFound && !loaded)` 里 `mode !==
'public'` 一处;再看测试 `FormPage.publicNotFound-27756.test.tsx`。
- 两分钟验证:`pnpm --dir ui exec vitest run
apps/console/src/components/FormPage.publicNotFound-27756.test.tsx`,预期 3
个用例全绿(zh 下 404 显示「页面不存在」、500 显示「表单加载失败」,页面均无英文)。
- 需要你做的:无,席位落地。
## What changes
- `loadPublicForm` threw `Failed to load form (STATUS): BODY` for every
non-OK `GET /forms/:slug`, and the page rendered that string verbatim in
its error banner to the anonymous visitor, in every session language,
with the server's body in it.
- A 404 from the resolver now throws the module-private
`FormNotFoundError` that #27446 added for the internal route (its
constructor now takes the message, so each loader names its own
subject). The resolver answers 404 for a slug that is unknown,
unpublished or no longer anonymous; the page draws the console's shared
not-found state with the `console.notFound.title` /
`console.notFound.description` keys.
- **Go back on the public route:** omitted. The visitor is a guest who
arrived from a shared link, often in a fresh tab, so `navigate(-1)` has
no console page to return to and is either a dead button or leaves the
site. The internal route keeps its Go back button unchanged.
- Every other non-OK answer throws a new module-private
`PublicFormUnavailableError` (status kept for logs). The page keeps it
in its own `publicUnavailable` flag and draws the error banner with the
existing `form.errorLoading` key ("Error loading form" / zh 「表单加载失败」),
translated at render. The response body is no longer read at all.
- No `@object-ui/i18n` key is added and no pack value changes
(`Clause-②: no`). All ten packs already carry `console.notFound.*` and
`form.errorLoading`.
## Tests
- New
`ui/apps/console/src/components/FormPage.publicNotFound-27756.test.tsx`,
at the real `/f/:slug` route with no provider wrapped around it:
- zh, 404: the state shows the zh title and description, and the page
body holds no Latin word;
- en, 404: `Page not found`, no button at all, no `Failed to load form`
and no server body text;
- CONTROL, zh, 500: the banner shows 「表单加载失败」, no not-found state, and
the page body holds no Latin word (so no server body).
- Ablation: with `FormPage.tsx` restored to the merge base `6d8372a8`,
all 3 cases fail (`Unable to find an element by:
[data-testid="form-not-found"]` twice,
`[data-testid="form-load-failed"]` once). Restored from `HEAD`, the
file's hash matched the HEAD blob (`b27577ca`).
<details><summary>Local runs (head 9390a5a)</summary>
- `pnpm --dir ui exec vitest run apps/console/src/components/FormPage`
(all `FormPage*` suites): Test Files 40 passed (40), Tests 369 passed
(369).
- `pnpm --filter @object-ui/console run type-check`: exit 0 (the console
tsconfig includes `src`, so the new test is compiled).
- `pnpm --dir ui exec vitest run scripts/`: Test Files 169 passed, 2
skipped (171).
- `pnpm check:new-line-citations` (ui): 0 new citations.
- `node scripts/check-sdui-manifest.mjs` and the rest of the
`dispatch-gates --commands` list (33 families): exit 0 each, reconciled
with `--ran` (33 run, 0 NOT-MEASURED).
- Before pushing, `ui/` was grepped for `Failed to load form`: the only
source hit is the message `PublicFormUnavailableError` keeps for logging
(plus the new test's own negative assertion). No existing test pinned
the old text.
</details>
## Acceptance notes
- The public route's not-found description is the shared
`console.notFound.description` ("The URL you followed does not match any
view in this app."), reused as the card asks. It is accurate for a
guest, though it speaks of "views"; a guest-specific line would be a new
key and is not in this card's scope.
## Verification
In a zh-CN session, open `/_console/f/no_such_slug`: the page shows
「页面不存在」 and its description, with no button and no English text.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01Utp6CbDAucNyQ4UtzCJKyh)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent e7dda2c commit 2a0b37b
3 files changed
Lines changed: 173 additions & 18 deletions
File tree
- .changeset
- ui/apps/console/src/components
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1595 | 1595 | | |
1596 | 1596 | | |
1597 | 1597 | | |
1598 | | - | |
1599 | | - | |
1600 | | - | |
1601 | | - | |
| 1598 | + | |
| 1599 | + | |
| 1600 | + | |
| 1601 | + | |
| 1602 | + | |
| 1603 | + | |
1602 | 1604 | | |
1603 | 1605 | | |
1604 | 1606 | | |
| |||
1720 | 1722 | | |
1721 | 1723 | | |
1722 | 1724 | | |
1723 | | - | |
1724 | | - | |
1725 | | - | |
1726 | | - | |
| 1725 | + | |
| 1726 | + | |
| 1727 | + | |
| 1728 | + | |
| 1729 | + | |
1727 | 1730 | | |
1728 | 1731 | | |
1729 | 1732 | | |
1730 | | - | |
1731 | | - | |
| 1733 | + | |
| 1734 | + | |
1732 | 1735 | | |
1733 | 1736 | | |
1734 | | - | |
1735 | | - | |
| 1737 | + | |
| 1738 | + | |
1736 | 1739 | | |
1737 | 1740 | | |
1738 | 1741 | | |
1739 | 1742 | | |
| 1743 | + | |
| 1744 | + | |
| 1745 | + | |
| 1746 | + | |
| 1747 | + | |
| 1748 | + | |
| 1749 | + | |
| 1750 | + | |
| 1751 | + | |
| 1752 | + | |
| 1753 | + | |
| 1754 | + | |
| 1755 | + | |
| 1756 | + | |
| 1757 | + | |
1740 | 1758 | | |
1741 | 1759 | | |
1742 | 1760 | | |
| |||
1761 | 1779 | | |
1762 | 1780 | | |
1763 | 1781 | | |
1764 | | - | |
| 1782 | + | |
1765 | 1783 | | |
1766 | 1784 | | |
1767 | 1785 | | |
| |||
2371 | 2389 | | |
2372 | 2390 | | |
2373 | 2391 | | |
| 2392 | + | |
| 2393 | + | |
| 2394 | + | |
| 2395 | + | |
| 2396 | + | |
| 2397 | + | |
| 2398 | + | |
2374 | 2399 | | |
2375 | 2400 | | |
2376 | 2401 | | |
| |||
2457 | 2482 | | |
2458 | 2483 | | |
2459 | 2484 | | |
| 2485 | + | |
2460 | 2486 | | |
2461 | 2487 | | |
2462 | 2488 | | |
| |||
2483 | 2509 | | |
2484 | 2510 | | |
2485 | 2511 | | |
| 2512 | + | |
2486 | 2513 | | |
2487 | 2514 | | |
2488 | 2515 | | |
| |||
2859 | 2886 | | |
2860 | 2887 | | |
2861 | 2888 | | |
| 2889 | + | |
| 2890 | + | |
| 2891 | + | |
2862 | 2892 | | |
2863 | 2893 | | |
2864 | 2894 | | |
2865 | 2895 | | |
2866 | 2896 | | |
2867 | | - | |
2868 | | - | |
2869 | | - | |
2870 | | - | |
2871 | | - | |
| 2897 | + | |
| 2898 | + | |
| 2899 | + | |
| 2900 | + | |
| 2901 | + | |
| 2902 | + | |
| 2903 | + | |
2872 | 2904 | | |
2873 | 2905 | | |
2874 | 2906 | | |
2875 | 2907 | | |
| 2908 | + | |
| 2909 | + | |
| 2910 | + | |
| 2911 | + | |
| 2912 | + | |
| 2913 | + | |
| 2914 | + | |
| 2915 | + | |
| 2916 | + | |
| 2917 | + | |
| 2918 | + | |
| 2919 | + | |
2876 | 2920 | | |
2877 | 2921 | | |
2878 | 2922 | | |
| |||
0 commit comments