Files
scaffold/template/.claude/rules/frontend-runtime.md
T
baozaotumao 39fe248f9f feat: 重组为标准 skill 包结构 + 修复 verify.sh bash 3.2 兼容
- 新增 .claude/skills/new-project/SKILL.md(标准 skill 格式)
- install-skill.sh 安装时组装 SKILL.md + verify.sh,单一源无重复
- verify.sh 改用索引数组替代 declare -A,兼容 macOS bash 3.2
- log_pass/log_skip 显式 return 0,避免 set -e 下非 verbose 误退出
- README 改为 skill 优先;补全 copier.yml/scripts/template 入库
2026-06-01 21:19:45 -07:00

3.0 KiB
Raw Blame History

paths
paths
frontend/**

frontend-runtime

前端运行时规范:错误处理三层防线、日志、WebSocket 消息验证、页面交互状态流。

错误处理三层防线

1. 组件级 ErrorBoundary(捕获渲染异常)

// components/ErrorBoundary.tsx
class ErrorBoundary extends React.Component {
  componentDidCatch(error: Error) {
    logger.error('Component error', { error: error.message })
    toast.error('页面渲染出错,请刷新重试')
  }
  render() {
    return this.state.hasError ? <FallbackUI /> : this.props.children
  }
}

2. WebSocket 消息验证失败(Zod parse 异常)

// hooks/useWebSocket.ts
try {
  const msg = wsMessageSchema.parse(JSON.parse(event.data))
  dispatch(msg)
} catch (e) {
  // 验证失败:记录日志,不更新状态,不崩溃
  logger.warn('Invalid WS message', { raw: event.data, error: e })
}

3. 全局未捕获异常

// main.tsx
window.addEventListener('unhandledrejection', (event) => {
  logger.error('Unhandled promise rejection', { reason: event.reason })
  toast.error('发生未知错误,请检查网络后重试')
})

错误展示规则

错误类型 展示方式
WebSocket 连接失败 Toasterror+ 重连提示
Gemini 超时/失败 聊天气泡(系统消息)+ Toast
文件下载失败 Toasterror
组件渲染崩溃 ErrorBoundary fallback UI

日志规范(utils/logger

使用轻量前端日志库或自封装(dev 输出 console,prod 静默或上报):

// utils/logger.ts
const logger = {
  info: (msg: string, ctx?: object) => {
    if (import.meta.env.DEV) console.info(`[INFO] ${msg}`, ctx)
  },
  warn: (msg: string, ctx?: object) => {
    console.warn(`[WARN] ${msg}`, ctx)
  },
  error: (msg: string, ctx?: object) => {
    console.error(`[ERROR] ${msg}`, ctx)
    // prod 环境可接入 Sentry / 自建上报
  },
}

禁止在组件/hooks 中直接使用 console.log,统一用 logger

WebSocket 消息验证

收到消息必须先 Zod 验证(safeParse)再更新 store,验证失败不崩溃只记录:

const msg = wsMessageSchema.safeParse(JSON.parse(event.data))
if (!msg.success) {
  logger.warn('Invalid WS message', { error: msg.error.flatten() })
  return
}
dispatch(msg.data)

页面交互状态流

idle ──► dialog ──► previewing ──► generating ──► screenshotting ──► done
                                                                       │
                                                              refining ◄┘
状态 展示内容
idle 初始引导(语言/图片源选择)
dialog 聊天气泡 + ChatInput
previewing StylePicker3 个 iframe 预览卡片)
generating ProgressBar + 日志气泡
screenshotting ProgressBar(逐页进度)
done PreviewFrame + DownloadBar + ChatInputrefine
error 错误气泡 + 重试按钮