Skip to content

错误收集 ​

自动捕获 JS 异常、Promise 拒绝、资源加载失败、白屏、API 失败,并支持手动上报。

错误收集由 ErrorPlugin 提供,需要 opt-in 显式装配,受 errors Consent 管控。可在 Playground · 错误收集 在线体验各错误子类的采集。

如何使用 ​

ts
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始终开
promiseunhandledrejection始终开
resource资源加载失败captureResource(默认开)
white-screen白屏检测captureWhiteScreen(默认开)
apifetch/XHR HTTP 失败captureApi(默认关)
ssrSSR 服务端错误captureSsr(默认关,见 SSR 采集)

装配方式 ​

ErrorPlugin 构造参数是 ErrorPluginOptions(字段全可选,分采集开关、控量、白屏、本地分级四组):

ts
// 全用默认:自动采集 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 ​

先速查,再展开重要项:

选项类型默认值说明
captureResourcebooleantrue采集资源加载失败
captureWhiteScreenbooleantrue白屏检测(无 DOM 自动 no-op)
captureApibooleanfalse采集 fetch/XHR HTTP 失败(侵入操作)
captureSsrbooleanfalse采集 SSR 服务端错误(需服务端注入容器)
detectTamperbooleanfalse原生方法篡改检测(安全信号)
errorRateLimitnumber100全局滑动窗口限流条数
rateWindowMsnumber60000限流窗口 ms
errorSessionMaxnumber5每指纹会话上限(含首次)
whiteScreenDelaynumber1000首屏白屏判定延迟 ms
whiteScreenContainersstring[]html/body/#app/#__nuxt/#root/#__next空容器选择器白名单
errorLevelsPartial<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)> 本地 > 默认。
ts
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 关系)。可匹配字段受子类白名单约束:

子类可匹配字段
jsmessage · fileName · stack · href
promise / ssrmessage · stack · href(ssr 另有 url)
api / resourcemessage · url · href(resource 另有 tagName)
white-screen无字段白名单,只落默认级

运算符:= / contains / match(正则)/ > < >= <=;级别取值 record / mention / major。

手动上报 ​

自动采集之外,可在业务里主动上报。两个方法的区别在于有没有 Error 对象、级别由谁定:

ts
// 已捕获的异常对象(带堆栈):第二参带业务上下文 extras,级别走分级规则
trace.captureException(err, { orderId: '8821' });
// 没有异常对象、只想报一句话/状态:第二参直接指定级别
trace.captureMessage('支付校验失败', 'major');
方法类型用在哪
captureException(error: unknown, extras?) => voidcatch 到的异常对象,保留堆栈,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,否则正常页面会漏判、空白页也测不出。

实现(启发式「采样点 + 空容器」):

  1. 触发:首屏 load 后延迟 whiteScreenDelay 判一次;SPA 路由切换重置"单页一次"并重判。单页至多上报一次,不参与折叠。
  2. 采样:在视口中心的横、竖两条线上取 17 个点(中心 1 + 横线 8 + 竖线 8,于 1/9…8/9 处均匀)。
  3. 判空:每点 elementsFromPoint 取栈顶元素,若栈顶就是某个空容器本身(无内容覆盖该点)→ 记一个空点。
  4. 判定:空点 ≥16/17 即白屏,emit 一条 white-screen 事件,extras 带 container/emptyPoints/samplePoints 便于排障。
  5. 降级:无 elementsFromPoint 能力整体 no-op;单点取到空数组(视口外)跳过不计(≠ 白屏);视口尺寸为 0 放弃本次判定。

SSR 错误捕获:接入与实现 ​

SSR 错误发生在浏览器之前,客户端 SDK 直接看不到。lens 用「服务端只采集 + 注入容器、客户端注水后统一上报」补上这段。

接入(两侧,详见 SSR 采集):

  • 客户端:new ErrorPlugin({ captureSsr: true })(默认关)。
  • 服务端:采集渲染期错误并注入 window.__TRIPO_SSR_ERR__ 容器(按框架接线,Nuxt 可直接用适配器)。服务端只采集 + 注入、绝不直发请求。
  • 容器不存在自然 no-op——所以客户端先打开也安全。

实现:

  1. 一次性读取(非订阅):setup 时读一次 window.__TRIPO_SSR_ERR__,读后立即清空(防注水多次触发重复上报);容器缺失直接返回。
  2. 归一:expandSsrErrors 防御坏输入(非数组 / 缺 message 的项丢弃),逐条喂入统一 _handle,子类 type: 'ssr'。
  3. 栈处理:服务端栈是单串,拆成帧数组并截断 ≤10 帧(与客户端栈口径一致),原样上报、不解析 SourceMap。
  4. 附加:extras 带 source: 'ssr-server',有 statusCode 则附上;容器中的 url 原样透传。ssr 的指纹按 message|topFrame 计算(url 仅 resource/api 子类用作指纹 seed)。
  5. 上报:归 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)。
  • 注意:全部字段见 装配方式;受 errors Consent 管控,未授权不 setup。

注意事项 ​

  • 错误内置默认 100% 放行、无节点级采样率,但可被远端 control.tech 坐标级规则降采样,也会被 error.filter(远端黑名单)和插件内控量(限流 / 会话上限)确定性地丢弃。
  • captureApi 默认关:它要包裹 fetch/XHR,属侵入操作;开启后会自动排除自身上报接口。
  • 白屏检测无 DOM 自动 no-op(小程序 / RN / SSR)。
  • 受 errors Consent 管控:未授权时不 setup、captureException 等 no-op。

下一步 ​

基于 MIT 协议发布(内部使用)