错误收集
自动捕获 JS 异常、Promise 拒绝、资源加载失败、白屏、API 失败,并支持手动上报。
错误收集由 ErrorPlugin 提供,需要 opt-in 显式装配,受 errors Consent 管控。可在 Playground · 错误收集 在线体验各错误子类的采集。
如何使用
import { TripoLens, ErrorPlugin } from '@tripo3d/lens';
const trace = new TripoLens({
app: 'shop',
configUrl: '...',
endpoint: '...',
plugins: [
new ErrorPlugin(), // 全默认即自动采集 js / promise / 资源 / 白屏
],
});
await trace.init();装上即生效,无需任何业务改动:全局 JS 异常、Promise 拒绝、资源加载失败、白屏都会自动上报。api / ssr / 篡改检测默认关,按需在 装配方式 里打开。
验证是否生效
临时触发一个错误(如 throw new Error('test') 或 Promise.reject('test')),在 Network 面板观察发往 /v2/trace/events 的请求。
错误类型:子类即 event_type
错误不塞 payload.source,而是子类直接作为 event_type,"是不是错误"由信封尾段 <app>.Error 表达。共 6 个子类,每个对应一类来源和一个采集开关——后面的装配、分级、进阶都按这 6 个子类展开:
event_type | 来源 | 开关 |
|---|---|---|
js | 全局 error / 手动 captureException·captureMessage | 始终开 |
promise | unhandledrejection | 始终开 |
resource | 资源加载失败 | captureResource(默认开) |
white-screen | 白屏检测 | captureWhiteScreen(默认开) |
api | fetch/XHR HTTP 失败 | captureApi(默认关) |
ssr | SSR 服务端错误 | captureSsr(默认关,见 SSR 采集) |
装配方式
ErrorPlugin 构造参数是 ErrorPluginOptions(字段全可选,分采集开关、控量、白屏、本地分级四组):
// 全用默认:自动采集 js / promise / 资源 / 白屏(不含 api / ssr / 篡改检测)
new ErrorPlugin();
// 按需打开 api 错误采集
new ErrorPlugin({ captureApi: true });
// 全字段细调(值均为默认值,按需覆盖)
new ErrorPlugin({
// 采集开关
captureResource: true, // 资源加载错误
captureWhiteScreen: true, // 白屏检测(无 DOM 自动 no-op)
captureApi: false, // api 错误 fetch/XHR HTTP 失败(侵入操作,默认关)
captureSsr: false, // SSR 服务端错误(需服务端注入容器)
detectTamper: false, // 原生方法篡改检测(安全信号)
// 控量(确定性,非随机采样)
errorRateLimit: 100, // 全局滑动窗口限流条数
rateWindowMs: 60000, // 限流窗口 ms
errorSessionMax: 5, // 每错误指纹会话上限
// 白屏
whiteScreenDelay: 1000, // 首屏白屏判定延迟 ms
whiteScreenContainers: ['html', 'body', '#app', '#__nuxt', '#root', '#__next'], // 空容器白名单
// 本地分级规则(按错误子类分组,详见下文「本地分级」)
errorLevels: {},
});ErrorPluginOptions
先速查,再展开重要项:
| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
captureResource | boolean | true | 采集资源加载失败 |
captureWhiteScreen | boolean | true | 白屏检测(无 DOM 自动 no-op) |
captureApi | boolean | false | 采集 fetch/XHR HTTP 失败(侵入操作) |
captureSsr | boolean | false | 采集 SSR 服务端错误(需服务端注入容器) |
detectTamper | boolean | false | 原生方法篡改检测(安全信号) |
errorRateLimit | number | 100 | 全局滑动窗口限流条数 |
rateWindowMs | number | 60000 | 限流窗口 ms |
errorSessionMax | number | 5 | 每指纹会话上限(含首次) |
whiteScreenDelay | number | 1000 | 首屏白屏判定延迟 ms |
whiteScreenContainers | string[] | html/body/#app/#__nuxt/#root/#__next | 空容器选择器白名单 |
errorLevels | Partial<Record<子类, ErrorLevelRule[]>> | — | 本地分级规则(按子类分组) |
采集开关
captureResource(boolean,默认true):采集<img>/<script>/<link>等资源加载失败。captureWhiteScreen(boolean,默认true):启用白屏检测;无 DOM 环境自动 no-op。机制见 进阶 · 白屏检测。captureApi(boolean,默认false):采集 fetch/XHR 的 HTTP 失败(status≥400 或网络错)。属侵入操作(包裹 fetch/XHR)故默认关;开启后自动排除 SDK 自身上报接口,防反馈环。captureSsr(boolean,默认false):采集 SSR 服务端错误(归ssr子类)。需服务端先注入容器,否则自然 no-op;机制见 进阶 · SSR 错误捕获。detectTamper(boolean,默认false):检测fetch/XHR/sendBeacon是否被篡改(安全信号,篡改归js错误)。
控量(确定性,非随机采样)
errorRateLimit(默认100)/rateWindowMs(默认60000):全局滑动窗口内最多上报多少条错误。errorSessionMax(默认5):每个错误指纹一个会话最多报几次(含首次),超限同指纹仅本地累计、不再上报。
白屏
whiteScreenDelay(默认1000):首屏load后延迟多少 ms 判一次白屏。whiteScreenContainers(默认html/body/#app/#__nuxt/#root/#__next):判定"页面是否为空"的空容器选择器白名单。
触发时机、采样算法与降级见 进阶 · 白屏检测。
本地分级
errorLevels:本地错误分级规则,按错误子类(js/promise/…)分组。优先级 远端(远程配置error.errorLevels)> 本地 > 默认。
new ErrorPlugin({
errorLevels: {
// api 错误:命中支付接口的提级为 major
api: [
{
conditions: [{
field: 'url',
operator: 'contains',
value: '/v2/payments'
}],
level: 'major'
},
],
// js 错误:ResizeObserver 噪音降级为 record(仅记录、不打扰)
js: [
{
conditions: [{
field: 'message',
operator: 'contains',
value: 'ResizeObserver'
}],
level: 'record'
},
],
},
});一条规则的 conditions 全部命中才算命中(AND 关系)。可匹配字段受子类白名单约束:
| 子类 | 可匹配字段 |
|---|---|
js | message · fileName · stack · href |
promise / ssr | message · stack · href(ssr 另有 url) |
api / resource | message · url · href(resource 另有 tagName) |
white-screen | 无字段白名单,只落默认级 |
运算符:= / contains / match(正则)/ > < >= <=;级别取值 record / mention / major。
手动上报
自动采集之外,可在业务里主动上报。两个方法的区别在于有没有 Error 对象、级别由谁定:
// 已捕获的异常对象(带堆栈):第二参带业务上下文 extras,级别走分级规则
trace.captureException(err, { orderId: '8821' });
// 没有异常对象、只想报一句话/状态:第二参直接指定级别
trace.captureMessage('支付校验失败', 'major');| 方法 | 类型 | 用在哪 |
|---|---|---|
captureException | (error: unknown, extras?) => void | catch 到的异常对象,保留堆栈,extras 附业务上下文 |
captureMessage | (message: string, level?) => void | 没有异常对象的消息/状态,level 取 'record' / 'mention' / 'major',缺省走分级规则 |
两者都归 js 子类、受 errors Consent 管控;未装插件或未授权时为 no-op。
进阶:白屏与 SSR
white-screen 与 ssr 两个子类的采集路径和其它错误不同,单独说清接入与实现。
白屏检测:接入与实现
接入:默认开(captureWhiteScreen !== false),纯客户端、无需额外接线;无 DOM 环境(小程序 / RN / SSR)自动 no-op。两处可调:whiteScreenDelay(首屏判定延迟,默认 1000)、whiteScreenContainers(空容器白名单)。
自定义根容器要登记
判定"页面为空"靠的是采样点栈顶正好是某个空容器。默认白名单覆盖 html/body/#app/#__nuxt/#root/#__next;若你的挂载点不在其中,必须加进 whiteScreenContainers,否则正常页面会漏判、空白页也测不出。
实现(启发式「采样点 + 空容器」):
- 触发:首屏
load后延迟whiteScreenDelay判一次;SPA 路由切换重置"单页一次"并重判。单页至多上报一次,不参与折叠。 - 采样:在视口中心的横、竖两条线上取 17 个点(中心 1 + 横线 8 + 竖线 8,于
1/9…8/9处均匀)。 - 判空:每点
elementsFromPoint取栈顶元素,若栈顶就是某个空容器本身(无内容覆盖该点)→ 记一个空点。 - 判定:空点 ≥16/17 即白屏,emit 一条
white-screen事件,extras带container/emptyPoints/samplePoints便于排障。 - 降级:无
elementsFromPoint能力整体 no-op;单点取到空数组(视口外)跳过不计(≠ 白屏);视口尺寸为 0 放弃本次判定。
SSR 错误捕获:接入与实现
SSR 错误发生在浏览器之前,客户端 SDK 直接看不到。lens 用「服务端只采集 + 注入容器、客户端注水后统一上报」补上这段。
接入(两侧,详见 SSR 采集):
- 客户端:
new ErrorPlugin({ captureSsr: true })(默认关)。 - 服务端:采集渲染期错误并注入
window.__TRIPO_SSR_ERR__容器(按框架接线,Nuxt 可直接用适配器)。服务端只采集 + 注入、绝不直发请求。 - 容器不存在自然 no-op——所以客户端先打开也安全。
实现:
- 一次性读取(非订阅):
setup时读一次window.__TRIPO_SSR_ERR__,读后立即清空(防注水多次触发重复上报);容器缺失直接返回。 - 归一:
expandSsrErrors防御坏输入(非数组 / 缺message的项丢弃),逐条喂入统一_handle,子类type: 'ssr'。 - 栈处理:服务端栈是单串,拆成帧数组并截断 ≤10 帧(与客户端栈口径一致),原样上报、不解析 SourceMap。
- 附加:
extras带source: 'ssr-server',有statusCode则附上;容器中的url原样透传。ssr的指纹按message|topFrame计算(url仅resource/api子类用作指纹 seed)。 - 上报:归
ssr子类(event_type=ssr),与其它错误一样内置默认 100% 放行(可被远端control.tech坐标级规则降采样)。
服务端的容器注入、并发请求归属等接线细节在 SSR 采集,本页只覆盖客户端这半。
实现原理
所有子类的采集面汇入同一条管线,再统一 emit:
采集(js/promise/resource/白屏/api/ssr)
→ 控量(确定性:前置过滤 → 指纹 → 会话上限 → 全局限流)
→ 分级(远端 > 本地 > 默认)
→ emit(P2,event_type=子类)→ L4 → L5错误走正常队列时序、不即时 flush(错误属可丢级,背压时最先被淘汰);重复错误的折叠计数由 L5 注入 context._amount。采样上错误内置默认 100% 放行、无节点级采样率(随机丢会漏关键错误),但可被远端 control.tech 坐标级规则降采样;"控量"主要靠上面的确定性手段,以及远程配置的 error.filter 前置过滤。
API 说明
手动错误捕获 API 经 trace 门面暴露(受 errors Consent 管控,未装 / 未授权时 no-op)。
trace.captureException(error, extras?)
- 含义与作用:手动捕获一个异常对象。
- 类型:
(error: unknown, extras?: Record<string, unknown>) => void。 - 注意:归
js子类;extras作为附加上下文随事件上报。
trace.captureMessage(message, level?)
- 含义与作用:手动上报一条消息(非 Error 对象)。
- 类型:
(message: string, level?: 'record' | 'mention' | 'major') => void。 - 注意:归
js子类;level缺省时走分级规则(远端 > 本地 > 默认)。
new ErrorPlugin(options?)
- 含义与作用:构造错误监控插件(opt-in,经构造参数
plugins装配)。 - 类型:
new ErrorPlugin(options?: ErrorPluginOptions)。 - 注意:全部字段见 装配方式;受
errorsConsent 管控,未授权不 setup。
注意事项
- 错误内置默认 100% 放行、无节点级采样率,但可被远端
control.tech坐标级规则降采样,也会被error.filter(远端黑名单)和插件内控量(限流 / 会话上限)确定性地丢弃。 captureApi默认关:它要包裹 fetch/XHR,属侵入操作;开启后会自动排除自身上报接口。- 白屏检测无 DOM 自动 no-op(小程序 / RN / SSR)。
- 受
errorsConsent 管控:未授权时不 setup、captureException等 no-op。
下一步
- 性能收集 · SSR 采集 · 远程配置 · error 节