ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

wewe-rss 前端错误监控实战:白屏与卡死的 3 层防御方案

wewe-rss 前端错误监控实战:白屏与卡死的 3 层防御方案 wewe-rss 前端错误监控实战白屏与卡死的 3 层防御方案【免费下载链接】wewe-rss更优雅的微信公众号订阅方式支持私有化部署、微信公众号RSS生成基于微信读书项目地址: https://gitcode.com/GitHub_Trending/we/wewe-rss上周有个用户反馈登录成功了可文章列表一直转圈点添加订阅源之后按钮没反应也没任何提示。打开控制台只有一行孤零零的 Uncaught 警告——这就是 wewe-rss 前端错误监控要解决的问题错误发生时用户侧往往是白屏、卡死或无响应而线索全部埋在你看不见的控制台里。1. 看清翻车现场为什么前端报错总是静默三个真实感很强的现场你大概率都遇到过白屏某个组件渲染时抛错整棵组件树被卸载页面直接空白转圈数据请求失败后没人接管加载态永远停在 isFetching无响应mutation 失败既没有成功提示也没有失败提示用户以为页面卡死了。共性原因只有一个前端错误的暴露渠道是浏览器控制台而用户不会打开它。更隐蔽的是两条加速器React 在渲染阶段遇到未捕获异常会直接卸载组件树不给你任何二次机会wewe-rss 用 React Query 管理请求默认会按 retry 策略自动重试非 401 最多 3 次。错误不会立刻爆发而是被压了几秒再出现——排查时你会发现时间点都对不上。所以上线前问自己一句如果这个错误只在控制台里出现我多久才能发现答案如果不能接受就需要往下搭监控。2. 拆解报错链路找到最容易漏掉的环节上一节回答了为什么静默这一节把一条报错从头到尾走一遍看它在哪一环会消失。以添加订阅源为例![wewe-rss 前端错误监控添加公众号源的操作界面]触发你粘贴链接点击确认pages/feeds/ 里的 handleConfirm 通过 tRPC 向服务端发起调用。请求走的是 provider/trpc.tsx 中配置的 httpBatchLink网络断、后端重启、链接解析失败都在这一步产生。传播结果先经过 React Query。它按 retry 函数决定重试几次然后才交给组件。注意 provider/trpc.tsx 里有个关键分支httpStatus 401时直接return false不重试因为重试也不会变出权限来。暴露组件拿到数据后渲染。这里最容易出渲染异常——比如账号列表页用statusMap[item.status].color取状态颜色一旦后端返回一个映射表里没有的 status 值.color就是 undefined 的访问链断裂直接炸在渲染里。最容易被漏掉的是这两个黑洞渲染异常没有 ErrorBoundary 时React 会把异常往上抛最终卸载整棵树——白屏且错误细节只进控制台未捕获的 Promise 拒绝很多操作写的是mutateAsync(...).then(() { ... })只接了成功分支。失败时这个 Promise 就变成 unhandled rejection浏览器默认只在控制台打一条警告页面毫无波澜。记住这两个黑洞下面三层防御就是照着它们修的。3. 搭建三层防御从全局兜底到交互反馈链路拆完我们按全局兜底 → 模块级 → 交互级三层来防每层都绑一个 wewe-rss 的真实模块示范。3.1 全局兜底用 ErrorBoundary 接住渲染异常渲染异常逃不掉只能接。React 18 里没有渲染异常的自动捕获机制标准做法是类组件形式的错误边界挂在整个应用树外层class ErrorBoundary extends React.Component { static getDerivedStateFromError(error) { return { hasError: true, error }; } componentDidCatch(error, info) { logError(error, info); // 上报点组件栈信息在这里 } render() { return this.state.hasError ? div页面出错了请刷新重试/div : this.props.children; } }在 App.tsx 里把 ErrorBoundary 包在 ThemeProvider 和 TrpcProvider 最外层路由切换、账号页、订阅页的渲染异常就都会被它拦住白屏变成一句可理解的提示。如何避免再踩坑ErrorBoundary 只拦渲染、生命周期、构造函数阶段的异常拦不住事件处理器和异步代码里的错误——所以它只是第一层别指望它一个扛全部。另外componentDidCatch拿到的errorInfo.componentStack能告诉你是哪个组件炸的上报时一定带上。3.2 模块级tRPC 请求失败统一兜底渲染异常拦住了还有一大半错误来自网络。好消息是 wewe-rss 已经把这一层做在了 provider/trpc.tsxQueryClient 的defaultOptions里同时配置了 queries 和 mutations 的onError401 弹无权限并清掉本地凭证跳登录页其余统一弹请求失败toast。也就是说任何没单独处理错误的请求失败都会落到这里用户至少能知道出了事。我们要补的只是两件事把这里的console.error升级成真正的上报调用带请求标识、HTTP 状态、脱敏后的参数检查每个retry是否合理——401 已处理像链接格式错误这种确定性失败重试只会多等几秒应直接置为不重试。如何避免再踩坑全局 onError 是保底提示不是业务处理。它适合弹一句通用的请求失败不适合替业务做决定比如是否清空表单、是否关弹层后者留给下一层。3.3 交互级具体操作的成功与失败都要有回音全局兜底管不出事交互级管体验闭环。看 pages/accounts/ 的删除账号成功时toast.success(删除成功!)后刷新列表——对称的做法是失败时也要有回音把 mutation 的失败分支接上deleteAccount(item.id).then(() { toast.success(删除成功!); refetch(); }).catch((err) { toast.error(删除失败, { description: err.message }); });再看 pages/feeds/ 的添加订阅它对每个链接先调 getMpInfo 解析解析出结果才走 addFeed解析不出来则toast.error(添加失败, { description: 请检查链接是否正确 })——这是交互级校验的示范把错误拦截在操作当场告诉用户具体下一步该做什么而不是甩一句请求失败。![wewe-rss 前端错误监控账号管理界面账号增删操作需要交互级错误反馈]如何避免再踩坑交互级提示要短、准、可行动。描述里写清请检查链接是否正确比写原始堆栈有用得多原始堆栈留给上报留给开发者。4. 一键复现与验证本地跑通 手动打一次报错三层搭完怎么确认它们真的生效先跑起来再亲手制造一次错误。最短跑通路径Node 20 pnpmgit clone https://gitcode.com/GitHub_Trending/we/wewe-rss cd wewe-rss pnpm install pnpm run build:web pnpm dev手动触发验证挑两个就能覆盖三层验证模块级打开 DevTools → Network把面板设为 Offline或把 serverOriginUrl 指到一个不可达地址刷新页面。预期看到 tRPC 请求失败 → 按 retry 重试 → 最终弹出请求失败toast。toast 出现说明 QueryClient 的兜底链路通了。验证全局级在任意页面组件里临时写一行throw new Error(test)仅本地验证后删掉刷新。预期页面变成 ErrorBoundary 的提示文案而不是白屏componentDidCatch的日志里能看到 componentStack。![wewe-rss 前端错误监控订阅内容管理界面可用于本地验证错误监控链路]验证完删掉临时代码。如何避免再踩坑把手动触发一次报错写进你的发布前习惯。监控代码最常见的死法是从来没跑过——今天没验证等于没有。5. 上线前检查清单照着打勾验证通过只是开始上线前这几项决定了你的监控是资产还是噪音上报去重同一错误同消息 同堆栈指纹在时间窗内只上报一次防止轮询类请求把同一错误刷几百条。隐私脱敏上报载荷里不得出现 Authorization token、账号 vid、完整用户输入。wewe-rss 的请求头里带凭证序列化参数前先过滤敏感字段。环境区分开发环境保留完整堆栈和 console 细节生产环境只上报精简文案。判断条件用import.meta.env.DEV/PROD别靠 if 写死。401 不重试确认 retry 策略对鉴权失败直接短路provider/trpc.tsx 已做改动后复查。提示文案不泄露toast 给用户看人话堆栈和状态码只进上报不进界面。监控自身失败要静默上报请求本身挂了不能反过来打断用户操作catch 住即可。收尾今天就动手做一件事打开 App.tsx给应用树套上一个 ErrorBoundary再用第 4 节的离线法打一次请求失败确认白屏、toast、上报日志三处都有回音。【免费下载链接】wewe-rss更优雅的微信公众号订阅方式支持私有化部署、微信公众号RSS生成基于微信读书项目地址: https://gitcode.com/GitHub_Trending/we/wewe-rss创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表