通过 Finch SDK 在你的应用中集成反馈收集、错误追踪与 OAuth 用户绑定。支持浏览器和 Node.js / Bun 服务端环境。
SDK 仅提供 API 接口能力,不包含 UI 组件。你可以灵活地在浏览器或服务端环境中使用。
npm install finch-feedback-sdk或使用 CDN(浏览器):
<script src="https://unpkg.com/finch-feedback-sdk/dist/index.global.js"></script>import { FinchSDK } from 'finch-feedback-sdk'
// 完全匿名(无任何身份信息)
const finch = new FinchSDK({
projectId: 'your-project-id',
apiUrl: 'https://your-finch-api.com',
environment: 'production', // 可选,标识当前运行环境
})
// 业务方已识别用户(外部用户)—— 后端会将反馈标记为 EXTERNAL
const finch2 = new FinchSDK({
projectId: 'your-project-id',
apiUrl: 'https://your-finch-api.com',
user: { id: 'biz-user-123', name: '张三', email: 'zhangsan@example.com' },
})
// finch 平台用户(内部用户)—— 传入 finchUserId,后端校验存在性后标记 INTERNAL
const finch3 = new FinchSDK({
projectId: 'your-project-id',
apiUrl: 'https://your-finch-api.com',
finchUserId: 'finch-user-abc',
})后端按下面优先级自动判定反馈来源:finchUserId 在 finch User 表存在视为 INTERNAL,仅带 user 画像视为 EXTERNAL,都没有则为 ANONYMOUS。内部用户也允许同时传 user 作为补充画像,控制台展示时优先显示 finch 用户身份。
⚠️ finchUserId 仅做存在性校验,不做密码学验证。被冒充的最坏后果只是垃圾反馈被抬高优先级,对本产品的威胁模型可接受。需要更高强度身份证明请走下面的 OAuth 登录 流程。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| projectId | string | 是 | 项目 ID,在 Finch 设置页获取 |
| apiUrl | string | 否 | Finch API 地址 |
| user | { id?, name?, email? } | 否 | 业务用户画像(外部用户);后端写入 reporter* 字段。也可在运行时通过 setUser() 动态切换 |
| finchUserId | string | 否 | finch 平台用户 ID;存在于 User 表则后端将反馈标记为 INTERNAL。也可在运行时通过 setFinchUserId() 动态切换 |
| environment | string | 否 | 当前运行环境标识(如 "production"、"staging"、"dev"),自动附加到所有上报数据,用于按环境筛选反馈和错误 |
| errors | ErrorConfig | 否 | 错误追踪配置,默认启用;传入 false 可完全禁用 |
| oauth | OAuthConfig | 否 | OAuth 配置,用于集成 Finch 登录 |
| snapshot | boolean | 否 | 提交反馈时自动捕获页面 HTML 快照(默认 true,服务端自动跳过) |
Finch SDK 提供运行时错误自动捕获和手动上报能力。SDK 会自动检测运行环境(浏览器 / Node.js),注册对应的全局错误处理器。
SDK 默认自动启用错误追踪,无需额外配置即可捕获全局错误和 console.error。如需自定义可传入 errors 配置:
const finch = new FinchSDK({
projectId: 'your-project-id',
apiUrl: 'https://your-finch-api.com',
// errors 配置可选,以下为默认值:
errors: {
captureGlobalErrors: true, // 自动拦截 window.onerror / unhandledrejection
captureConsoleErrors: true, // 拦截 console.error(捕获框架内部错误)
maxErrorsPerMinute: 10, // 客户端限流
ignorePatterns: [ // 忽略匹配的错误消息(正则字符串)
'ResizeObserver',
'Script error',
],
},
// 完全禁用错误追踪:errors: false,
})SDK 默认自动启用错误追踪,浏览器端会监听:
window.onerror — 捕获未处理的运行时错误unhandledrejection — 捕获未处理的 Promise 拒绝console.error — 拦截 console.error 调用(仍会正常输出到控制台),自动提取 Error 对象的堆栈信息import { FinchSDK } from 'finch-feedback-sdk'
const finch = new FinchSDK({
projectId: 'your-project-id',
apiUrl: 'https://your-finch-api.com',
// 默认自动启用,可选自定义:
errors: {
captureGlobalErrors: true, // 自动拦截 uncaughtException / unhandledRejection
captureConsoleErrors: true, // 拦截 console.error
maxErrorsPerMinute: 10,
},
})服务端环境会自动监听:
process.on('uncaughtException') — 捕获未处理异常process.on('unhandledRejection') — 捕获未处理的 Promise 拒绝内部定时器使用 unref(),不会阻止进程正常退出。
// 捕获 Error 对象
try {
riskyOperation()
} catch (error) {
await finch.captureError(error, {
context: 'payment-processing',
orderId: '12345',
})
}
// 上报消息(非 Error 对象)
await finch.captureMessage('用户触发了异常操作', 'WARNING', {
action: 'deleteAccount',
})Express / Hono 错误中间件:
app.use((err, req, res, next) => {
finch.captureError(err, {
method: req.method,
path: req.path,
})
res.status(500).json({ error: 'Internal Server Error' })
})Next.js App Router(error.tsx):
'use client'
import { useEffect } from 'react'
export default function ErrorBoundary({ error }: { error: Error }) {
useEffect(() => {
finch.captureError(error)
}, [error])
return <div>Something went wrong</div>
}SDK 和服务端协作实现三层去重,避免高频错误导致数据库爆炸:
| 层级 | 位置 | 策略 |
|---|---|---|
| 1. 客户端限流 | SDK | 默认每分钟最多上报 10 条错误 |
| 2. 短时去重 | 服务端 | 同一指纹在短时间窗口内重复到达,只递增计数,不创建新事件记录 |
| 3. 事件采样 | 服务端 | 高频错误按梯度采样存储详情(前 10 条全存,之后逐步降低采样率) |
错误发生次数(eventCount)始终精确累计,但实际存储的事件详情行数被有效控制。 相同代码路径产生的错误会通过堆栈指纹自动归类到同一个错误组。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| captureGlobalErrors | boolean | true | 自动拦截全局未处理错误 |
| captureConsoleErrors | boolean | false | 拦截 console.error 调用 |
| maxErrorsPerMinute | number | 10 | 每分钟最大上报数量 |
| ignorePatterns | string[] | [] | 忽略的错误消息模式(正则字符串) |
SPA 卸载或服务端关闭时调用 destroy() 移除所有监听器和定时器:
finch.destroy()// 不需要预先设置任何身份信息也能提交(匿名)
await finch.submitFeedback({
type: 'BUG', // BUG | UI | FEATURE | OTHER | AUTO
description: '在 Safari 浏览器下首页无法正常显示',
metadata: { // 自定义元数据(可选)
browser: 'Safari',
os: 'macOS',
},
})
// 业务方用户登录后调用 setUser,后续所有提交都会带上画像
finch.setUser({ id: 'biz-user-123', name: '张三', email: 'zhangsan@example.com' })
// 业务方用户登出
finch.clearUser()在浏览器端,SDK 默认会自动捕获页面 HTML 快照并上传。通过 snapshot 和 snapshotOptions 配置可自定义此行为。服务端环境会自动跳过快照捕获。
通过 Finch OAuth,你可以让用户使用 Finch 账号登录,自动关联反馈信息到用户身份。
在 Finch 项目设置 → OAuth 应用 中创建应用,获取 client_id 和 client_secret。
const finch = new FinchSDK({
projectId: 'your-project-id',
apiUrl: 'https://your-finch-api.com',
oauth: {
clientId: 'finch_xxxx',
redirectUri: 'https://yourapp.com/callback',
},
})
// 获取登录 URL,引导用户跳转
const loginUrl = finch.getLoginUrl()
window.location.href = loginUrl用户授权后会重定向到回调地址,携带 code 参数。在你的后端服务中换取 access_token:
// 后端处理回调 (Node.js 示例)
import { FinchClient } from 'finch-feedback-sdk'
const client = new FinchClient({
apiUrl: 'https://your-finch-api.com',
projectId: 'your-project-id',
})
// 用 code 换取 access_token(需要 clientSecret,仅在后端使用)
const token = await client.exchangeCode({
clientId: 'finch_xxxx',
clientSecret: 'fncs_xxxx',
redirectUri: 'https://yourapp.com/callback',
}, code)
// 获取用户信息
const user = await client.getUserInfo(token.access_token)
// => { id: 'user-id', name: '张三', email: 'user@example.com', image: '...' }
// 将 user.id 关联到你的系统用户// 用 access_token 拉取 finch 用户信息
const user = await finch.getUserInfo(token.access_token)
// 把 finch userId 喂给 SDK,之后所有提交都标记为 INTERNAL
finch.setFinchUserId(user.id)
await finch.submitFeedback({
type: 'BUG',
description: '页面加载异常',
})
// 用户登出时
finch.clearFinchUserId()说明:OAuth 流程在这里只是 finch 提供的「证明 finch 用户身份」的官方通道。如果接入方有自己的方式确认 finch 用户身份(比如先调过 /api/oauth/userinfo 然后把 userId 持久化),可以跳过这一步直接 setFinchUserId。
| 端点 | 方法 | 说明 |
|---|---|---|
| /api/oauth/authorize | GET | 授权端点,引导用户登录并授权 |
| /api/oauth/token | POST | 令牌端点,用授权码换取 access_token |
| /api/oauth/userinfo | GET | 用户信息端点,使用 Bearer token 获取用户资料 |
| 方法 | 说明 |
|---|---|
| setUser(user) | 设置业务用户画像(外部用户);后端落到 reporter* 字段 |
| clearUser() | 清除业务用户画像 |
| setFinchUserId(id) | 标记当前用户为 finch 平台用户;后端校验存在性后标 INTERNAL |
| clearFinchUserId() | 清除 finch 用户标识 |
| submitFeedback(data) | 提交反馈(无需预设身份,未识别时为匿名) |
| captureError(error, metadata?) | 手动捕获 Error 对象并上报 |
| captureMessage(msg, severity?, metadata?) | 手动上报消息(severity: ERROR / WARNING / INFO) |
| destroy() | 清理所有监听器和定时器 |
| uploadScreenshot(base64, mimeType) | 上传截图,返回 URL |
| getLoginUrl(state?) | 获取 OAuth 登录 URL |
| exchangeCode(code, clientSecret) | 用授权码换取令牌(后端使用) |
| getUserInfo(accessToken) | 获取 Finch 用户信息 |
| 环境 | 自动错误拦截 | 手动上报 | 反馈 + 快照 |
|---|---|---|---|
| 浏览器 | window.onerror / unhandledrejection | captureError / captureMessage | 全部支持 |
| Node.js / Bun | uncaughtException / unhandledRejection | captureError / captureMessage | 反馈支持,快照自动跳过 |
| CDN (IIFE) | 同浏览器 | Finch.FinchSDK | 全部支持 |
登录 Finch 后,进入项目设置页面即可找到 Project ID 并创建 OAuth 应用。 如果还没有账户,立即登录开始使用。