一、为什么要捕获用户行为导致的报错?
前端报错监控早已是标配,但仅有错误信息往往不足以快速定位问题。
我们经常面临的痛点:
- 报错重现难:用户说"点了保存就崩了",但你在本地就是复现不了。
- 错误信息不足 :跨域脚本报错只有
Script error.
,几乎无用。 - 缺少上下文:只知道某行报错,但不知道用户之前做了什么操作。
因此,一个完善的错误监控体系需要做到:
- 捕获错误(运行时、资源加载、Promise、框架内部)
- 记录用户行为(点击、输入、路由跳转)
- 结合 SourceMap 还原(定位到真实源码)
- 回放用户操作(还原 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[日志分析平台 / 回放工具]
总结
- 前端错误捕获手段包括:
onerror
、error
事件、unhandledrejection
、框架 ErrorBoundary。 - 单纯捕获错误不足以解决问题,需要 结合用户行为日志。
- 高级方案包括 会话录制(rrweb) 和 SourceMap 还原,帮助开发者快速定位 Bug。
- 工程落地时,可以封装一个前端监控 SDK,并结合后端日志平台(如 Sentry、阿里云 ARMS)做可视化。