Skip to content

fix(app-shell): announce the route object-read and page record-load failures - #27366

Merged
objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/project-thread-jplskw
Oct 29, 2026
Merged

objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/project-thread-jplskw

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Warren · project thread

Part of #25915 (slice 3 of ruling B; slice 4, the retirement of ViewSkeleton / ShimmerSkeleton, is the PR that closes the card).

Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:控制台里两处"加载失败"画面(路由对象读取失败、自定义页面记录读取失败)改用共享的 DataErrorState 组件绘制。
  • 为什么改:原来这两处用无 role 的 Empty 手绘,读屏软件在读取失败时什么都听不到;共享组件天生 role="alert",失败会被播报,也与"空"区分开。
  • 风险与回滚:只换呈现组件,文案、i18n 键、测试 id、重试按钮都不变;视觉上多一个红色小图标方块。回滚即还原这两个文件。
  • 先看:ui/packages/app-shell/src/views/PageView.tsx 的失败分支;ui/packages/app-shell/src/console/AppContent.tsx 的 RouteObjectReadFailed。
  • 两分钟验证:pnpm --dir ui exec vitest run packages/app-shell/src/views/__tests__/PageView.appPageRecord-12931.test.tsx,预期全部通过,含新增的 #25915 用例。
  • 需要你做的:无,席位落地。

What changes

  • RouteObjectReadFailed (ui/packages/app-shell/src/console/AppContent.tsx) and the page record-scope load failure (ui/packages/app-shell/src/views/PageView.tsx) render DataErrorState from @object-ui/components instead of a hand-drawn Empty. The failure node is now role="alert" by construction.
  • Kept unchanged: the i18n keys and defaults (list.loadErrorTitle / list.loadErrorMessage, empty.recordLoadFailed / empty.recordLoadFailedDescription, common.retry), the test ids (route-object-read-failed, page-record-load-failed and their -retry buttons) and both Retry handlers.
  • No new prop on the shared component: the test id spreads onto the root through ...props, and Retry is passed as children (the component's documented slot for a call site's own control) rather than onRetry, so it keeps its own test id and, on the page, its icon. The shared default icon (destructive AlertCircle square) replaces the page block's muted AlertTriangle; AlertTriangle drops from the page's imports.
  • Changeset: @object-ui/app-shell is private: true, but its code ships inside the published @object-ui/console SPA, so the changeset bumps both as patch (the same pair recent app-shell fixes carry).

Tests

  • New pin in AppContent.disabledPackageDeepLink-13052.test.tsx: on a 5xx read the route-object-read-failed node has role="alert" and contains its Retry; Retry asks once more and the served object renders with no alert. The existing served-object CONTROL also asserts no alert.
  • New pin in PageView.appPageRecord-12931.test.tsx: the failed read's node has role="alert" and contains Retry; Retry re-reads, the loaded row renders, and no alert remains.

Acceptance notes

Other app-shell blocks that draw a load failure by hand (listed for the card; not moved here, per the order): views/metadata-admin/AuditPanel.tsx (audit-error-state, an Empty), views/metadata-admin/ResourceEditPage.tsx (refs-error, an Empty), views/metadata-admin/DirectoryPage.tsx (the engine.directory.loadFailed line, a bare text-destructive div), and chrome/ErrorBoundary.tsx (the boundary fallback, an Empty). objectViewHeaderChrome.tsx also has one but is under the ObjectView* exclusion.

Verification

All readings at head 72976b7a (base eef83734).

Tests and ablation
  • The two touched files, under os-verify-lock: pnpm --dir ui exec vitest run --maxWorkers=2 on both. VERDICT command-exit 0, Test Files 2 passed (2), Tests 23 passed (23).
  • Ablation, with the fix committed: both source files reverted to origin/main (the Empty blocks: a grep -c for the DataErrorState JSX opener reads 0 in each file, and for the old Empty opener carrying the test id reads 1 in each). VERDICT command-exit 1, Tests 2 failed | 21 passed (23). The two #25915 pins went red on toHaveAttribute('role', 'alert'), and every other test stayed green. Restored with git checkout HEAD --: both blob hashes equal HEAD, git diff HEAD empty.
  • Every app-shell test file that imports AppContent or PageView (56 files), under the lock: VERDICT command-exit 0, Test Files 56 passed (56), Tests 358 passed (358).
  • pnpm --filter @object-ui/app-shell type-check (tsc --noEmit + tsc -p tsconfig.test.json), after building @object-ui/app-shell^...: VERDICT command-exit 0, 0 error TS.
Gates
  • dispatch-gates --commands --repo objectstack-ai/objectstack derived 34 families. All 34 ran, each with its exit code captured before any pipe, and all 34 exited 0 (pnpm --dir ui exec vitest run scripts/ ran under the lock: 174 files passed, 2 skipped). --ran reconciliation: 34 derived, 34 run, 0 NOT-MEASURED.
  • dispatch-gates --tier: no path-derived mandate.
  • pnpm --dir ui run check:new-line-citations: 0 new citations, exit 0.
  • Changed lines: 129 (+89 / -40), under the 3000 human-merge threshold.

Generated by Claude Code

…ailures

RouteObjectReadFailed (AppContent) and the page record-scope load failure
(PageView) drew an Empty with no role, so assistive technology heard
nothing when the read failed. Both now render the shared DataErrorState
(role="alert" by construction), keeping their i18n keys and defaults,
their test ids and their Retry controls (passed as children).

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JQwxbZK9w6fe2Y6mGQjj6L
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:ui#1 · os-warren · session_01JQwxbZeBv2y91towxasSUT

席位核对

ACCEPT · seat domain:ui#1 · head 72976b7a · 2026-10-29T03:31Z

席位意见:Console 里两个加载失败块(路由对象读取失败、自定义页记录读取失败)原来画的是没有 role 的 Empty,读屏软件听不到;现在改由共享的 DataErrorState 绘制,天生 role="alert"。标题、文案、i18n 键、test id、重试按钮都不变,没有给共享组件加新 prop(test id 走 props 透传,重试按钮放在 children)。符合裁决 B(6486367718)和派发单 6486381447 的 slice 3。

  1. Shape: Part of #25915; 5 files, +89/−40: console/AppContent.tsx (RouteObjectReadFailed), views/PageView.tsx (AppPageRecordRead failure), one new case in each block's existing test file, .changeset/25915-load-failures-data-error-state.md (@object-ui/app-shell + @object-ui/console patch).
  2. Premise measured: seat read both blocks on origin/main before the claim (an Empty, no role). The ⛔ Studio empty states, ObjectView*, RecordDetailView.tsx and seat 2's packages are untouched.
  3. Gates / check-runs: PR check-runs on 72976b7a: 44 success, 11 skipped, 0 failure; mergeable_state clean. Dev's local run: 23/23 on the two test files, the 56 dependent app-shell test files (358 tests) green, type-check exit 0, 34/34 derived gates exit 0 (--ran reconciled). Ablation: reverting either block to Empty reds its role pin.
  4. Accepted deviations: a changeset despite app-shell being private: true — its code ships in the published @object-ui/console (not private on main), so the app-shell + console patch pair is the repo's practice; pins added as new cases in the existing test files rather than new files; the visible change is DataErrorState's destructive icon square (the page block's muted AlertTriangle goes, the route block gains an icon).
  5. Out of scope: four more hand-drawn load failures in app-shell (AuditPanel, ResourceEditPage, DirectoryPage, chrome/ErrorBoundary) are noted in the report, not moved, per the order's "move only these two". Slice 4 (retiring ViewSkeleton / ShimmerSkeleton) follows on the same branch after this merges, under claim amendment 6487017457. Skills-docs: none — presentation only.
  6. Landing: not Tier H; Clause-②: no. The seat readies and arms auto-merge.

Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 29, 2026 03:33
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 29, 2026 03:33
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 29, 2026
Merged via the queue into main with commit c4c515a Oct 29, 2026
56 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-jplskw branch October 29, 2026 03:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tooling Fix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants