From 2ced38769bbc320ebcd93720f7d388f9f980cdac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=A8=E9=9C=96=E9=93=83?= Date: Fri, 22 May 2026 20:49:46 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E6=9B=B4=E6=96=B0PageErrorBoundary?= =?UTF-8?q?=E7=9A=84=E6=96=87=E6=A1=88=E5=92=8C=E6=A0=B7=E5=BC=8F=E4=BB=A5?= =?UTF-8?q?=E5=AF=B9=E9=BD=90shadcn=E4=B8=BB=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 错误提示从“该页面加载失败”改为“该功能运行异常” - 重试按钮文字从“重试”改为“重新尝试” - 使用border-destructive, bg-destructive等语义化类名替换硬编码颜色 - 更新对应测试断言 --- components/PageErrorBoundary.tsx | 46 +++++++++++++------ .../__tests__/PageErrorBoundary.test.tsx | 18 ++++---- 2 files changed, 41 insertions(+), 23 deletions(-) diff --git a/components/PageErrorBoundary.tsx b/components/PageErrorBoundary.tsx index 37c3fba..6bb511e 100644 --- a/components/PageErrorBoundary.tsx +++ b/components/PageErrorBoundary.tsx @@ -14,7 +14,7 @@ interface State { /** * 页面级错误边界组件:捕获子组件树中的 JavaScript 错误 - * 与全局 ErrorBoundary 的区别:使用轻量内嵌卡片 UI,提供重试按钮 + * 完美适配 shadcn/ui 语义化主题与暗黑模式 */ export class PageErrorBoundary extends Component { state: State = { @@ -43,27 +43,45 @@ export class PageErrorBoundary extends Component { render() { if (this.state.hasError) { return ( -
-
- -

该页面加载失败

-

- 页面在加载或渲染时遇到错误,您可以重试或切换到其他工具。 +

+ {/* + 1. 适配暗黑模式的容器设计: + 不再使用 border-red-200 / bg-red-50,改用标准的 border-destructive/20 和 bg-destructive/5, + 并在黑夜模式下会自动转为深红底色,绝不刺眼。 + */} +
+ {/* 2. 状态符号改用标准的 text-destructive 语义色 */} +
+ +
+ +

该功能运行异常

+

+ 该页面在加载或渲染时遇到了内部脚本错误。您可以尝试重试,或者通过导航菜单切换到其他工具。

+ + {/* 3. 错误日志展示:使用与 shadcn 贴合的深色代码块包裹 */} {this.state.error && ( -
-
-                  {this.state.error.toString()}
+              
+
+                  {this.state.error.stack || this.state.error.toString()}
                 
)} + + {/* + 4. 严谨调用 shadcn 原子 Button: + 去掉全部手动指定的红底白字类名,直接启用 variant="destructive"。 + 它会自动处理 hover 颜色变化、暗黑模式切换以及无障碍高亮边框。 + */}
diff --git a/components/__tests__/PageErrorBoundary.test.tsx b/components/__tests__/PageErrorBoundary.test.tsx index fb9078d..bf33240 100644 --- a/components/__tests__/PageErrorBoundary.test.tsx +++ b/components/__tests__/PageErrorBoundary.test.tsx @@ -34,7 +34,7 @@ describe('PageErrorBoundary', () => { , ); - expect(screen.getByText('该页面加载失败')).toBeInTheDocument(); + expect(screen.getByText('该功能运行异常')).toBeInTheDocument(); expect(screen.getByText(/测试错误/)).toBeInTheDocument(); }); @@ -45,7 +45,7 @@ describe('PageErrorBoundary', () => { , ); - expect(screen.getByText('该页面加载失败')).toBeInTheDocument(); + expect(screen.getByText('该功能运行异常')).toBeInTheDocument(); // 将子组件替换为正常组件,然后点击重试 rerender( @@ -54,14 +54,14 @@ describe('PageErrorBoundary', () => { , ); - const retryButton = screen.getByRole('button', { name: /重试/ }); + const retryButton = screen.getByRole('button', { name: /重新尝试/ }); retryButton.click(); await waitFor(() => { expect(screen.getByTestId('normal-content')).toHaveTextContent('恢复后的内容'); }); - expect(screen.queryByText('该页面加载失败')).not.toBeInTheDocument(); + expect(screen.queryByText('该功能运行异常')).not.toBeInTheDocument(); }); it('resetKey 变化时自动重置错误状态', async () => { @@ -71,7 +71,7 @@ describe('PageErrorBoundary', () => { , ); - expect(screen.getByText('该页面加载失败')).toBeInTheDocument(); + expect(screen.getByText('该功能运行异常')).toBeInTheDocument(); // 切换 resetKey,同时提供正常子组件 rerender( @@ -84,7 +84,7 @@ describe('PageErrorBoundary', () => { expect(screen.getByTestId('normal-content')).toHaveTextContent('页面 B 内容'); }); - expect(screen.queryByText('该页面加载失败')).not.toBeInTheDocument(); + expect(screen.queryByText('该功能运行异常')).not.toBeInTheDocument(); }); it('resetKey 不变时保持错误状态', () => { @@ -94,7 +94,7 @@ describe('PageErrorBoundary', () => { , ); - expect(screen.getByText('该页面加载失败')).toBeInTheDocument(); + expect(screen.getByText('该功能运行异常')).toBeInTheDocument(); // 仅 children 变化,resetKey 不变,错误应保持 rerender( @@ -103,7 +103,7 @@ describe('PageErrorBoundary', () => { , ); - expect(screen.getByText('该页面加载失败')).toBeInTheDocument(); + expect(screen.getByText('该功能运行异常')).toBeInTheDocument(); }); it('错误 UI 包含重试按钮', () => { @@ -113,7 +113,7 @@ describe('PageErrorBoundary', () => { , ); - const retryButton = screen.getByRole('button', { name: /重试/ }); + const retryButton = screen.getByRole('button', { name: /重新尝试/ }); expect(retryButton).toBeInTheDocument(); });