关于前端监控用户行为导致的报错

一、为什么要捕获用户行为导致的报错?

前端报错监控早已是标配,但仅有错误信息往往不足以快速定位问题。

我们经常面临的痛点:

  • 报错重现难:用户说"点了保存就崩了",但你在本地就是复现不了。
  • 错误信息不足 :跨域脚本报错只有 Script error.,几乎无用。
  • 缺少上下文:只知道某行报错,但不知道用户之前做了什么操作。

因此,一个完善的错误监控体系需要做到:

  1. 捕获错误(运行时、资源加载、Promise、框架内部)
  2. 记录用户行为(点击、输入、路由跳转)
  3. 结合 SourceMap 还原(定位到真实源码)
  4. 回放用户操作(还原 Bug 现场)

二、前端报错的常见类型与捕获方式

2.1 运行时错误( js 执行报错)

js 复制代码
window.onerror = function(message, source, lineno, colno, error) {
  console.log('运行时错误:', { message, source, lineno, colno, error });
};

注意点

  • 对于跨域的脚本,可能只会返回 Script error.,解决方案是在 <script> 标签加 crossorigin="anonymous",并在服务端设置 Access-Control-Allow-Origin

2.2 资源加载错误(图片这类的外部资源)

js 复制代码
window.addEventListener('error', (event) => {
  if (event.target && (event.target.src || event.target.href)) {
    console.log('资源加载失败:', event.target.src || event.target.href);
  }
}, true);
// 第三个参数必须是 true,才能捕获捕获阶段的资源错误

2.3 Promise 未捕获(未 catch 的)错误

js 复制代码
window.addEventListener('unhandledrejection', (event) => {
  console.log('未捕获的 Promise 错误:', event.reason);
});

注意点

  • 如果你 catch 了,就不会触发 unhandledrejection
  • async/await 场景下,未加 try/catch 的错误也会走这里

2.4 框架内部错误

例如 vue3

js 复制代码
app.config.errorHandler = (err, vm, info) => {
  console.error("Vue 捕获错误:", err, info);
};

三、如何捕获用户行为

单纯捕获错误不足以定位问题,我们需要记录 用户行为链路

3.1 简单埋点方案

  • 点击事件
  • 输入框值变化
  • 路由切换
js 复制代码
const actions = [];

document.addEventListener('click', e => {
  actions.push(`点击: ${e.target.tagName} ${e.target.innerText}`);
});

window.addEventListener('popstate', () => {
  actions.push(`路由跳转: ${location.pathname}`);
});

3.2 高级方案:录制用户会话

利用第三方库 rrweb 可以记录用户的 DOM 交互,甚至支持回放。 这样当报错发生时,你不仅能拿到错误堆栈,还能通过回放还原用户的真实操作。

四、错误与用户行为的绑定

flowchart TD A[用户操作] --> B[记录行为日志] B --> C[触发错误] C --> D[错误捕获机制] D --> E[错误信息 + 行为日志打包] E --> F[上报服务端] F --> G[日志分析平台 / 回放工具]

总结

  • 前端错误捕获手段包括:onerrorerror 事件、unhandledrejection、框架 ErrorBoundary。
  • 单纯捕获错误不足以解决问题,需要 结合用户行为日志
  • 高级方案包括 会话录制(rrweb)SourceMap 还原,帮助开发者快速定位 Bug。
  • 工程落地时,可以封装一个前端监控 SDK,并结合后端日志平台(如 Sentry、阿里云 ARMS)做可视化。
相关推荐
无羡仙1 小时前
从零构建 Vue 弹窗组件
前端·vue.js
源心锁2 小时前
👋 手搓 gzip 实现的文件分块压缩上传
前端·javascript
源心锁2 小时前
丧心病狂!在浏览器全天候记录用户行为排障
前端·架构
GIS之路2 小时前
GDAL 实现投影转换
前端
烛阴3 小时前
从“无”到“有”:手动实现一个 3D 渲染循环全过程
前端·webgl·three.js
BD_Marathon3 小时前
SpringBoot——辅助功能之切换web服务器
服务器·前端·spring boot
Kagol3 小时前
JavaScript 中的 sort 排序问题
前端·javascript
eason_fan3 小时前
Service Worker 缓存请求:前端性能优化的进阶利器
前端·性能优化
光影少年3 小时前
rn如何和原生进行通信,是单线程还是多线程,通信方式都有哪些
前端·react native·react.js·taro
好大哥呀4 小时前
Java Web的学习路径
java·前端·学习