CnOps 智能运维与可观测社区
首页开源项目实践文章视频课程常见问答开发者工具STAROps 专题
导航菜单
首页开源项目实践文章视频课程常见问答开发者工具STAROps 专题

CnOps 智能运维与可观测社区

愿景

CnOps 智能运维与可观测社区是一个以"智能运维与可观测"为核心的开放、包容、分享的技术社区,旨在聚集运维专家、开发者和爱好者,共同探讨、学习和分享可观测最佳实践与最新技术,与众多技术社区合作互动,共同探讨交叉领域的技术挑战,推动可观测领域的创新与进步。

内容社区

  • 实践文章
  • 视频课程
  • 开源项目
  • 常见问答
  • 开发者工具

友情链接

  • Prometheus
  • Grafana Lab
  • OpenTelemetry
  • LoongCollector

关注我们

阿里云云原生公众号阿里云云原生
阿里云可观测公众号阿里云可观测

Copyright © 2026 CnOps 社区. All rights reserved.

首页实践文章STAROps 前端排障实战:从 React 报错到源码定位与修复验证

STAROps 前端排障实战:从 React 报错到源码定位与修复验证

#RUM#STAROps#前端排障#全链路可观测

CNOps | 2026-10-14

改了一处折扣金额的展示逻辑,商品详情页不能加购了,结算页也无法支付。页面没有白屏,导航仍然正常,购买流程却走不下去了。我们在 React 电商演示应用 web-react-demo 中模拟了这次故障,用它来演示如何通过 RUM 排查前端问题。

5eecdaf48460cde5bccb0f4961a4e56f4cd225362839048e75b8339e1c4c24831b75b38faadcd24bec177c308ebd5304f316f0a93d664f4d03f093413d9ecf2777e95fea5a49ae2100de0158fc0a66206bfafa67316caa0e4fb4c8ed7016461c.png

两个页面报的都是同一个 toFixed 空值错误。查看 JS 堆栈,可以找到出错的折扣格式化函数;但要弄清这个函数为什么影响了两个页面,还需要看 React 组件堆栈。RUM SDK 会在捕获 React 渲染异常时,一并记录出错组件及其父组件。本例中,这份堆栈让我们找到了商品报价和订单汇总两个业务组件:它们都使用了同一个折扣展示组件,也因此受到了同一处缺陷的影响。

这篇文章记录了用 STAROps 排查这次故障的过程:查询受影响的页面,还原源码和组件堆栈,然后对比修复前后的加购、支付记录,确认用户能继续完成操作。后续版本则由 Mission 定期检查,持续观察错误和性能变化。文中的截图来自实际分析过程,也提供了免登入口,可以直接打开演示数据继续提问。

直接体验

点击下面的入口即可免登体验,查看演示应用最近 7 天的前端报错:

  • 点击即分析:查看最近 7 天的前端报错。
  • 自由体验 STAROps Playground。

本文使用 2026 年 9 月 15 日 10:26—10:32(北京时间)的演示数据。进入后可在同一对话中继续追问;若样本已过期,需要换用有数据的时间范围。

一、演示应用与 React 异常采集

演示应用提供商品浏览、加购、结算和模拟支付,并接入 @arms/rum-browser-react。在初始化 RUM 后调用 initReactPlugin(ArmsRum),再用 SDK 提供的 ErrorBoundary 包住商品报价和订单汇总组件。

当这些组件渲染出错时,SDK 会把 error.stack 和 React 提供的 errorInfo.componentStack 一起上报:前者记录函数执行时的调用栈,后者记录出错组件及其父组件层级。两份堆栈随同一次异常保存,后面可以结合页面、版本和 SourceMap 分析。

下图中,结算页的报价区域已切换到降级界面,模拟支付无法继续,商店导航仍可使用。异常虽然被 ErrorBoundary 捕获,RUM 中仍保留了这次错误及其组件堆栈。

5eecdaf48460cde5bccb0f4961a4e56f4cd225362839048e75b8339e1c4c24831b75b38faadcd24bec177c308ebd5304931d540059acc3e40ce5a0beb5c3ae6244f0a8012eb16e52e1d6d40e1b3b0288efa15da5151508c44fb4c8ed7016461c.png

图 1:结算页的报价区域报错,无法继续模拟支付。

演示包含三个版本,分别呈现异常出现前、出现后和修复后的行为:

版本作用折扣字段缺失时的行为
1.0.0正常基线使用空值保护,操作可以继续
1.1.0演示回归调用 undefined.toFixed,报价组件报错
1.1.1修复版本恢复空值保护,操作可以继续

三个版本都已上传与运行 JS 匹配的 SourceMap。它将两类堆栈中的压缩文件行列位置映射回源码:既能找到实际抛错的语句,也能找到 React 业务组件的定义位置。

接入与上传步骤可参考 Web/H5 接入文档和 CMS2 CLI 符号表上传文档。

二、哪些页面受到影响

先在 STAROps 中询问这段时间的报错情况:

帮我看看 web-react-demo 在 2026 年 9 月 15 日 10:26 到 10:32(北京时间)为什么报错,影响了哪些页面?

5eecdaf48460cde5bccb0f4961a4e56f4cd225362839048e75b8339e1c4c24831b75b38faadcd24bec177c308ebd5304771af113e42693f1d20959c2ab82052eaa29ff83b015137a1fb9152ad1cb689eaf6d959cbf5e21704fb4c8ed7016461c.png

图 2:报错集中在商品详情页和结算页。

STAROps 查到 5 次 TypeError,全部来自 1.1.0,错误信息均为 Cannot read properties of undefined (reading 'toFixed'):

  • 商品详情页 /products/:productId:3 次。
  • 结算页 /checkout:2 次。

三、报错对应哪一行代码

STAROps 根据异常堆栈中的 JS 文件和行列位置,查询对应的 SourceMap,定位到了 src/App.tsx 第 271 行:value!.toFixed(2)。它位于折扣格式化函数 formatDiscount 中。

5eecdaf48460cde5bccb0f4961a4e56f4cd225362839048e75b8339e1c4c24831b75b38faadcd24bec177c308ebd5304c4491cbb03af748189e1b078dd7858e863b5e4aa425e651b96d138fa765f28c1d2eb5077113702414fb4c8ed7016461c.png

图 3:报错定位到折扣格式化函数中的 value!.toFixed(2)。

export function formatDiscount(value?: number): string {
  if (release.stage === 'regression') {
    return value!.toFixed(2);
  }
  return (value ?? 0).toFixed(2);
}

异常版本进入 regression 分支。当折扣字段缺失时,value 是 undefined,调用 toFixed 就会报错。这里的 ! 只是 TypeScript 非空断言,运行时不会替代码补上空值检查。

演示应用把缺失折扣视为无折扣。修复后使用 (value ?? 0).toFixed(2),先将缺失值替换为 0,再格式化显示。

四、用 React 组件堆栈还原业务路径

本例两个页面的 JS 错误堆栈相同:前两帧分别是 formatDiscount 和 DiscountAmount,其余帧来自 React 内部的渲染代码。它能定位到第 271 行的 toFixed,但其中没有商品报价组件 ProductOffer 或订单汇总组件 OrderSummary。

React 组件堆栈补充了出错组件在组件树中的位置。继续问 STAROps:

这两个页面各自经过哪些业务组件?请根据实际组件堆栈还原。

STAROps 读取 RUM SDK 采集的 React 组件堆栈,并使用对应构建的 SourceMap 还原压缩组件名。两个页面都出现了 DiscountAmount,它们的业务父组件却不同:

5eecdaf48460cde5bccb0f4961a4e56f4cd225362839048e75b8339e1c4c24831b75b38faadcd24bec177c308ebd530490c8a64c44b826333bace3cff3bbd0b4e3bf13e629927d8533676443d59988e7aa82b08922294c6f4fb4c8ed7016461c.png

图 4a:商品详情页的 React 组件堆栈。SourceMap 将 Kh、Jh 还原为 DiscountAmount、ProductOffer,并保留 SDK ErrorBoundary 帧。

5eecdaf48460cde5bccb0f4961a4e56f4cd225362839048e75b8339e1c4c24831b75b38faadcd24bec177c308ebd530479b2e0b3c8f2e69d22e504f755386887d2e664381e8bc393fa588458c05ac3b5438b1303115eaf794fb4c8ed7016461c.png

图 4b:结算页的 React 组件堆栈。同一个 DiscountAmount 的业务父组件变为 OrderSummary。

商品详情页的 Jh 对应 App.tsx:284 的 ProductOffer,结算页的 $h 对应 App.tsx:331 的 OrderSummary;两份组件堆栈中的 Kh 都对应 App.tsx:276 的 DiscountAmount。这些是组件定义的位置,实际抛错语句仍是第 271 行。

结合组件堆栈和源码,可以整理出下面的关系。组件层级按父组件到子组件排列,只保留关键业务组件:

页面React 组件层级组件内的抛错位置
商品详情ProductOffer → DiscountAmountformatDiscount,App.tsx:271
结算OrderSummary → DiscountAmountformatDiscount,App.tsx:271

两条组件路径指向同一个 DiscountAmount,它渲染时调用的 formatDiscount 没有处理缺失的折扣值。因此,这次需要修复共享的格式化函数,并检查商品报价和订单汇总两个区域。JS 堆栈给出了修改哪一行,React 组件堆栈给出了哪些业务组件使用了这段代码。

五、1.1.1 发布后,报错是否恢复

上线一段时间后,直接追问

修复版本 1.1.1 上线并积累一段时间的访问数据后,可以回到同一对话中问:

web-react-demo 的 1.1.1 已经上线一段时间了。最近 1 小时,Cannot read properties of undefined (reading 'toFixed') 这个报错还出现吗?如果还有,是旧版本还是 1.1.1?商品详情页的加购和结算页的支付恢复了吗?

这次查询聚焦 1.1.1 的访问量、原报错是否仍然出现,以及加购成功的 cart_added、模拟支付成功的 order_paid 事件。如果旧版本仍有报错,也能按版本区分,避免把它算到修复版本上。

下面是本文演示数据中的版本对比结果:

5eecdaf48460cde5bccb0f4961a4e56f4cd225362839048e75b8339e1c4c24831b75b38faadcd24bec177c308ebd530490c8a64c44b826333bace3cff3bbd0b4e3bf13e629927d8533676443d59988e7aa82b08922294c6f4fb4c8ed7016461c.png

图 5:演示样本中各版本的加购与模拟支付事件,商品和结算分别统计。

在本次已入库的折扣缺失样本中,1.1.0 的 3 个商品会话和 2 个结算会话均发生异常;1.1.1 对应的 3 个商品会话完成了加购,2 个结算会话完成了模拟支付,均未复现该异常。

用 Mission 持续观察后续发布

如果希望每次发布后都自动检查,可以在 STAROps 中创建一个长期任务,选择「RUM 发布观察」模板:

为 web-react-demo 创建一个长期的发布观察任务,每小时检查一次。自动发现新版本,对比它与此前稳定版本的 JS 错误、页面和接口性能,持续观察 24 小时,并把报告保存在任务中。

本例已创建 web-react-demo 发布观察 Mission(免登查看),每小时第 5 分钟运行。后续发布新版本时,可以打开同一个任务查看执行记录和观察报告。

5eecdaf48460cde5bccb0f4961a4e56f4cd225362839048e75b8339e1c4c24831b75b38faadcd24bec177c308ebd5304c2f46afd3739ce450de686321a4f216fe9916070e31c60d54f55e9020ce8c5dfebe98e144c81cf574fb4c8ed7016461c.png

图 6:web-react-demo 的发布观察计划,每小时检查一次,自动识别版本并对比错误和性能。

任务于 2026 年 9 月 15 日 12:05 自动触发,约 4 分 38 秒后完成并生成了首次观察报告(免登查看)。这次回看过去 24 小时,共识别 3 个版本、70 个会话,查询范围比前面的案例截图更大。

报告在 1.1.0 中查到 11 次 toFixed 错误,影响 10 个会话;1.1.1 没有出现这条错误,但 /api/orders 和 /api/quote 的 p90 延迟约为 1.4 秒。任务把这些接口列了出来,便于继续排查。

5eecdaf48460cde5bccb0f4961a4e56f4cd225362839048e75b8339e1c4c24831b75b38faadcd24bec177c308ebd5304e65ca9255bf854f701cdad8faa049623ef95ee7ddbf836be418315c04ad84897f14bdcbab46ca3cd4fb4c8ed7016461c.png

图 7:首次自动执行报告中的接口延迟对比,1.1.1 的订单与报价接口延迟偏高。

本次 1.1.1 只有 19 个会话,后续还需积累样本、继续观察。每轮执行记录和报告都会保存在同一个 Mission 中。

结语

这次排查中,JS 堆栈把错误定位到 formatDiscount,React 组件堆栈进一步指出它分别影响 ProductOffer 和 OrderSummary。RUM SDK 的 React 支持,让被错误边界捕获的渲染异常也能带着组件上下文进入分析。修复后,再查看加购、支付是否恢复,并用 Mission 持续观察后续版本的错误和性能。

可以打开 STAROps 免登演示,从文首的问题开始体验,再在同一对话里继续追问。

文章大纲

推荐文章

超过 2000+ 位开发者正在阅读

给 OpenClaw 加上企业级 Memory

给 OpenClaw 加上企业级 Memory

4646 阅读

阿里云 STAROps 全域智能运维平台发布!

阿里云 STAROps 全域智能运维平台发布!

3453 阅读

阿里云正式发布 RCA Benchmark

阿里云正式发布 RCA Benchmark

2716 阅读

推荐视频

UModel 最佳实践 Vol.1 UModel 数据建模全景解读

UModel 最佳实践 Vol.1 UModel 数据建模全景解读

3854 观看50:35
云监控2.0全景:可观测范式升级与智能运维蓝图

云监控2.0全景:可观测范式升级与智能运维蓝图

2532 观看41:06

推荐工具

精选可观测领域开发者工具

云监

云监控 2.0 沙箱体验

7483 使用

免费

免费网络拨测工具

2746 使用