npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@composy/error-core

v0.0.2

Published

Framework-agnostic error management core for LDesign

Readme

@composy/error-core

LDesign 错误处理核心包,提供框架无关的错误模型、捕获、上报、事件、作用域和 Engine bridge。所有框架适配包都应优先复用本包能力,避免复制捕获、去重、限流、上报和诊断逻辑。

安装

pnpm add @composy/error-core

分层职责

  • catcher:捕获运行时错误、Promise 拒绝、资源错误、网络错误和可选的 console 错误。
  • reporter:批量上报、重试、采样、卸载发送和 IndexedDB 离线缓存。
  • manager:组合 catcher、reporter 和 emitter,提供统一门面 API。
  • scope:为同步或异步流程追加 tags、extra、breadcrumbs 和 userId。
  • engine:把 ErrorManager 注册到 LDesign Engine 的 state / events。
  • utils:错误规范化、堆栈解析、指纹、限流、环境和 ID 工具。

配置与构建

  • .ldesign/eslint.config.js 和 .ldesign/tsconfig.json 是本包 ESLint / TypeScript 的权威配置。
  • 构建使用本目录 .ldesign/builder.config.ts 的 @composy/builder / rolldown 配置。
  • Playground TypeScript 配置位于 .ldesign/tsconfig.playground.json;tsconfig.json 路径保留兼容 shim。
  • pnpm run type-check 检查 core 源码和 Playground,pnpm run build 生成并校验发布产物。

快速使用

import { createErrorManager, ErrorLevel, withScopeAsync } from '@composy/error-core'

const manager = createErrorManager({
  autoReport: true,
  catcher: {
    captureNetworkErrors: true,
    enableDeduplication: true,
    maxErrorsPerMinute: 100,
  },
  reporter: {
    endpoint: '/api/errors',
    batchSize: 10,
    sampleRate: 1,
  },
})

manager.on('error', (error) => {
  console.info('[error captured]', error.message)
})

manager.install()

manager.captureMessage('用户进入结算页', ErrorLevel.INFO)

await withScopeAsync(async (scope) => {
  scope.setTag('module', 'checkout')
  scope.setExtra('orderId', 'SO-1001')
  scope.addBreadcrumb({
    type: 'click',
    category: 'ui',
    message: 'submit order',
  })

  await submitOrder()
})

诊断与维护

getDiagnostics() 返回只包含副本的快照,适合调试面板、日志、健康检查和问题复现。

const diagnostics = manager.getDiagnostics()

console.info(diagnostics.stats.total) // 总错误数
console.info(diagnostics.catcher.rateLimitRemaining) // 限流剩余
console.info(diagnostics.reporter.queueLength) // 上报队列长度

配置边界

数值配置会在运行时归一化,避免无效值让错误链路失效:

  • maxErrors、reporter.batchSize 和 reporter.maxQueueSize 最低为 1。
  • reporter.sampleRate 会限制在 0 到 1;timeout 最低为 1ms。
  • catcher.maxBreadcrumbs 和 maxErrorsPerMinute 最低为 0。0 分别表示不保留面包屑,以及在限流启用时拒绝所有捕获。
  • 重试次数、缓存数量和时间间隔会截断为非负整数;NaN 与无穷值回退为默认值。

运行时开关与去重聚合

ErrorCatcher#setOptions() 支持在应用运行中切换捕获策略。它会保留当前 session、用户和 breadcrumbs;如果实例已经 install(),更新时会先释放旧的全局事件、网络和 console lease,再按新配置重新安装,避免旧监听器继续生效。将 enabled 设为 false 会同时阻止全局与手动捕获;重新启用后需要显式调用 install() 才会恢复全局监听。

catcher.setOptions({
  captureNetworkErrors: false,
  captureConsoleErrors: true,
  maxErrorsPerMinute: 50,
})

当同一 fingerprint 在去重窗口内再次出现时,重复事件仍会触发 ignored,但 ErrorManager 会在已保存的错误上累加 count 并更新 lastSeen,同时保留 firstSeen。这样既不会扩大内存队列,也不会让诊断面板丢失错误发生频率。

ErrorReporter#report() 对采样率采用半开区间语义:sampleRate: 0 始终不入队, sampleRate: 1 始终入队;这避免随机值恰好为 0 时突破零采样策略。

Reporter 内存队列默认最多保留 10,000 条。容量已满时,新到的采样通过错误会被丢弃,已有队列顺序保持不变; onQueueOverflow 每次 report() / reportBatch() 溢出时报告丢弃数量,回调异常会被隔离。getDiagnostics() 提供累计 overflowCount;reporter.maxQueueSize 可在创建时设置,也可通过 setOptions() 动态调整,缩小时会保留队列头部并裁掉尾部。 reportBatch() 会在整批采样和容量裁剪后统一调度一次发送。 IndexedDB 中待补发的记录只按剩余容量逐条恢复,并在成功交付后继续补入;持久化副本在收到成功 ack 前保留。

数据安全边界

  • 错误、网络和资源上下文中的 URL 会移除 query/hash,只保留 origin 与 pathname。
  • captureConsoleErrors 会对循环对象、bigint 和抛出异常的 toString 做安全降级,并遮盖 password、token、secret、authorization、cookie 与 apiKey 等字段。
  • ErrorScope(0) 表示不保留面包屑;ErrorCatcher#setOptions() 可以在运行时切换捕获策略,同时保留当前session、用户和仍在容量范围内的面包屑。

全局监听生命周期

ErrorCatcher 通过 addEventListener 注册全局错误和未处理 Promise 拒绝监听,不会覆盖应用既有的 window.onerror 或 window.onunhandledrejection。多个 ErrorManager 可以同时安装,任一实例卸载只会移除自身监听器。

网络与控制台捕获使用共享拦截器分发给已安装实例,不会随着多个 ErrorManager 形成多层 fetch、XHR 或 console 包装;仅最后一个实例卸载时才恢复宿主函数。

ErrorManager#destroy() 与 ErrorReporter#destroy() 均为终态操作。管理器会立即停止接受安装与捕获;上报器会等待正在处理的请求完成或将失败批次交回内存/离线缓存,再关闭缓存连接。并发销毁调用等待同一次清理;销毁 Promise 完成后,迟到任务不会重新激活资源或触发业务回调。

Reporter 的离线缓存按 appId、endpoint 和 schemaVersion 命名空间隔离。缓存恢复只把数据取得内存队列,不会提前清空持久化副本;只有成功交付并完成 cache ack 后才删除对应记录。发送失败、beforeSend 抛错或持久化失败时,批次会保留在内存队列或重新写入缓存,避免静默丢失。

ErrorReporter#setOptions() 可动态更新发送与卸载行为;enableOfflineCache 及启用离线缓存时的 appId、endpoint、schemaVersion 创建后固定。需要切换缓存开关或命名空间时,请创建新的 Reporter,避免把一个应用的离线错误发送到另一个端点。

ErrorCatcher 的网络与 console 观察通过 browserPatchBroker 共享。Reporter 请求带有 x-ldesign-error-owner: telemetry:error-reporter 标记,网络捕获器会忽略该 owner,避免错误上报请求再次触发错误上报。

Node 环境下 withScopeAsync() 自动使用 AsyncLocalStorage。浏览器若已有异步上下文实现,可调用 setErrorScopeContextCarrier() 注入 { get, run } carrier;没有 carrier 时仅能保证同步作用域安全。

核心 API

| API | 说明 | | ------------------------------------------------------------------------- | -------------------------------------------- | | createErrorManager(options) | 创建统一错误管理器 | | ErrorManager#install() / uninstall() | 安装或卸载全局捕获 | | ErrorManager#captureError() / captureMessage() / captureErrorInfo() | 手动捕获错误 | | ErrorCatcher#setOptions() | 运行时更新捕获开关并同步监听器 | | ErrorManager#flush() | 立即发送上报队列 | | ErrorManager#getStats() | 读取错误统计 | | ErrorManager#getDiagnostics() | 读取不可变诊断快照 | | ErrorReporter#flush() | 并发调用会复用正在进行的 flush,避免重复请求 | | withScope() / withScopeAsync() | 执行作用域逻辑,并保留 callback 返回值 | | createErrorEnginePlugin() | 注册 Engine 插件 |

源码注释

本包所有源码文件均包含完整的中文逐行注释,涵盖:

  • 每个模块/类/函数的用途和设计说明
  • 参数、返回值和异常的详细描述
  • 使用示例和最佳实践
  • 性能考虑和兼容性说明
  • 内部实现细节和算法解释

类型安全

本包严格禁止使用 any 类型,所有接口和工具类型都使用完整的类型定义:

  • Record<string, unknown> 替代 Record<string, any>
  • 回调参数使用精确类型定义
  • 工具类型使用 unknown 而非 any
  • 泛型约束确保类型安全

构建产物

本包显式使用 @composy/builder 的内置 rolldown,构建后保持四类产物:

| 目录 | 说明 | 入口 | | ------- | -------------------------- | ----------------------- | | es/ | ESM + 类型声明 | module / types 入口 | | esm/ | 保留模块结构和 Less 源样式 | 二次构建入口 | | lib/ | CommonJS 产物 | main 入口 | | dist/ | UMD 与压缩 UMD 产物 | CDN 入口 |

postbuild 会归一化声明、CJS 扩展名、样式和压缩 UMD,再检查入口字段、所有 exports、sourcemap、lib/package.json 与完整目录契约;任一缺失都会让构建失败。

本地验证

# 类型检查
pnpm --dir packages/error/packages/core run type-check

# 运行测试
pnpm --dir packages/error/packages/core run test:run
pnpm --dir packages/error/packages/core run test:watch

# 构建
pnpm --dir packages/error/packages/core run build
pnpm --dir packages/error run outputs:check

相关链接

License

MIT © LDesign Team