# 定位错误与还原堆栈

找到出错的更新 hash，使用同次构建的 sourcemap 还原代码位置。

## 按这个顺序定位 {#start}

1. **记录出错版本**：从出错设备的 `getUpdateMetadata().currentVersion` 获取更新 hash，同时记录时间与原生版本。
2. **取到错误堆栈**：使用已采集的 JS 错误或现有崩溃平台报告，不要只保存截图。
3. **找到同次构建的映射**：必须匹配实际发布的 `.ppk`；重新 bundle 得到的 map 不能替代。
4. **还原与验证**：运行下方 symbolicate，核对文件和行号，再修复并走测试发布。

## 为什么需要它 {#why}

SDK 会随 JS 错误上报当前更新版本、原生版本和堆栈。先定位出错版本，再用对应 sourcemap 把压缩代码的位置还原成源码文件和行号。

## 默认开启的上报 {#automatic}

SDK 初始化后自动链入 React Native 的全局 `ErrorUtils`——它不会替换你已有的异常处理器，而是串联在其后：

- 未捕获的 JS 异常会自动上报；
- 上报内容：错误消息、JS 堆栈、更新版本信息与基础设备信息；
- 上报通道与更新遥测共用同一套服务配置。

不想要 JS 错误上报时单独关闭：

```tsx
const updateClient = new Pakta({
  appKey,
  disableErrorReporting: true, // 仅关闭 JS 错误上报
  // disableTelemetry: true,   // 连更新生命周期遥测一起关闭
});
```

## 手动上报 {#capture}

业务代码里的捕获异常（比如你在接口层 try/catch 了）默认不会上报，需要时主动提交：

```tsx
// 复用根组件外创建的现有 client。

try {
  await riskyCheckout();
} catch (error) {
  client.captureException(error, { context: 'checkout' });
}
```

上下文对象会随错误一起入库，写你排查时需要的业务标识即可。

## 与崩溃平台关联 {#crash-report}

原生崩溃、ANR 这类 JS 管道之外的异常，交给 Sentry / Crashlytics，而 Pakta 负责把**当前更新版本信息**注入它们的报告：

```tsx
import * as Sentry from '@sentry/react-native';
import { attachToSentry } from 'rn-update';

// 在已有 Sentry 初始化之后调用，传入实例。
attachToSentry(Sentry);
```

Sentry 面板里按 `pakta.currentVersion` 过滤，就能回答“这次崩溃集中在哪个热更新版本”。

## 还原堆栈 {#symbolicate}

`bundle` 默认生成 sourcemap，`publish --sourcemap` 归档后，用 CLI 把线上错误堆栈还原为源码位置：

```bash
pakta symbolicate stack.txt --platform android --hash <UPDATE_HASH>
```

`hash` 可从 `getUpdateMetadata().currentVersion` 取得；Hermes 工程的最终映射在打包时已自动合成，无需额外处理。见[命令行工具](/docs/cli#diagnostics)。

> [!IMPORTANT] 隐私边界
> 不要在错误上下文或自定义字段里写入令牌、密码或个人信息；上报的字段会原样进入服务端存储。

## 没有还原出行号时 {#verify}

先检查 `publish --sourcemap` 是否成功归档、hash 是否来自出错版本、平台是否正确。设备仍运行内置 bundle 时 currentVersion 为空，应使用原生构建自己的映射流程。没有当时的 map，就不能保证从压缩堆栈恢复准确行号。
