You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

283 lines
7.9 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# H5 错误上报功能说明
## 概述
已为H5项目添加了全局错误上报功能能够捕获和上报前端运行时错误即使发生白屏也能获取到错误信息。
## 错误上报接口
- **接口地址**: `https://tj-h5.hnxdfe.com/api/H5/test`
- **请求方式**: POST
- **Content-Type**: application/json
## 上报的错误类型
### 1. JavaScript 运行时错误 (type: 'error')
- 语法错误
- 引用错误
- 类型错误
- 范围错误等
### 2. Promise 未处理错误 (type: 'promise')
- Promise rejection 错误
- async/await 未捕获的异常
### 3. uni-app 错误 (type: 'uni-app-error')
- uni-app 生命周期错误
- 页面加载错误
### 4. 早期错误 (type: 'error' / phase: 'early')
- 应用初始化前的错误
- 脚本加载错误
- 白屏问题的主要来源
### 5. 手动上报错误 (type: 'manual')
- 业务逻辑中的自定义错误
## 错误数据格式
```json
{
"type": "error", // 错误类型
"message": "xxx is not defined", // 错误信息
"stack": "Error: xxx...", // 堆栈信息
"url": "https://...", // 当前页面URL
"ua": "Mozilla/5.0...", // 用户代理
"timestamp": "2024-01-01T00:00:00.000Z", // 时间戳
"openId": "xxxxx", // 用户OpenID如果存在
"phase": "early" // 阶段标识(仅早期错误)
}
```
## 功能特性
### 1. 多重上报保障
错误上报采用三层保障机制,确保即使白屏也能上报:
1. **优先使用 navigator.sendBeacon**
- 即使页面关闭也能发送
- 不阻塞页面卸载
- 最可靠的方式
2. **备用方案 fetch with keepalive**
- keepalive 选项保证请求完成
- 适用于大多数浏览器
3. **兜底方案 uni.request**
- 使用 uni-app 的请求方法
- 100ms 延迟避免阻塞
### 2. 早期错误捕获
-`index.html` 中尽早初始化错误监听
- 捕获应用初始化前的错误
- 使用错误缓冲区存储早期错误
- 应用加载后统一重新上报
### 3. 性能监控
自动上报以下性能指标:
- `loadTime`: 页面总加载时间
- `domReadyTime`: DOM就绪时间
- `firstPaint`: 首次渲染时间
## 使用方法
### 自动捕获(默认开启)
所有错误会自动上报,无需额外配置。
### 手动上报错误
```javascript
// 在业务代码中手动上报
uni.$lu.errorReport.report('自定义错误信息', {
// 额外的业务数据
userId: '123',
action: 'submitOrder'
})
```
### 手动上报错误对象
```javascript
try {
// 可能出错的操作
} catch (error) {
uni.$lu.errorReport.reportError(error, 'custom-error')
}
```
### 上报性能数据
```javascript
uni.$lu.errorReport.reportPerformance({
customMetric: 1234,
operation: 'loadData'
})
```
## 日志输出
在开发环境中,可以在控制台看到以下日志:
```
[早期错误捕获] 已初始化
[错误上报] 已初始化
[错误上报] 早期错误数量: 2
[错误上报] { type: 'error', message: '...', ... }
```
## 后端处理建议
### 1. 数据存储
建议将错误数据存储到数据库或日志系统:
- MongoDB: 适合存储灵活的JSON数据
- MySQL/PostgreSQL: 可以使用JSON字段
- ELK Stack: 适合日志分析和检索
### 2. 错误统计
可以统计以下指标:
- 错误类型分布
- 错误发生频率
- 受影响的用户数
- 错误来源页面
- iOS vs Android 错误对比
### 3. 告警机制
可以设置告警规则:
- 某类错误短时间内激增
- 同一用户连续报错
- 白屏类型错误phase: 'early'
## 调试方法
### 1. 测试错误上报
在浏览器控制台执行:
```javascript
// 触发一个错误
throw new Error('测试错误上报')
```
### 2. 查看网络请求
打开开发者工具 -> Network -> 查看POST请求到 `/api/H5/test` 的数据
### 3. 查看早期错误缓冲区
```javascript
console.log(window.__ERROR_BUFFER__)
```
### 4. 小程序 WebView 设备调试(重要)
由于小程序 WebView 无法查看控制台,已添加以下调试功能:
#### 调试按钮
页面右下角会显示三个调试按钮:
1. **🐛 查看日志**(红色)- 切换日志面板显示/隐藏
2. **🧪 测试**(绿色)- 测试日志功能是否正常工作
3. **🗑️ 清空**(橙色)- 清空所有日志
#### 自动显示日志
- 发生错误时,页面顶部会自动显示黑色半透明的调试面板
- 面板中会显示完整的错误信息和调试日志
- 点击 "🐛 查看日志" 按钮可手动切换显示状态
#### 日志内容
日志面板中会显示:
- `[时间] [原始error事件]` - 原始错误事件的详细信息
- `[时间] [早期错误捕获]` - 处理后的错误信息
- `[时间] 调试系统已初始化` - 调试系统启动时的测试日志
- 所有调试日志的时间戳和详细信息
#### 测试日志功能
1. 点击 **🧪 测试** 按钮
2. 如果日志面板出现并显示测试信息,说明日志功能正常
3. 如果点击没反应,可能是被小程序 WebView 的安全策略限制
#### 获取完整日志
如果需要将日志发送给开发者:
方法1截图
- 将调试面板的内容截图
方法2复制日志
```javascript
// 在浏览器控制台执行(需要能访问控制台)
console.log(JSON.stringify(window.__DEBUG_LOGS__, null, 2))
```
方法3通过小程序调试工具
- 如果小程序有调试模式,可以通过调试工具访问 `window.__DEBUG_LOGS__`
#### 调试面板特性
- 自动滚动到最新日志
- 每条日志有分隔线,方便阅读
- 自动换行,长文本不会溢出
- 点击 "🐛 查看日志" 按钮切换显示/隐藏
## 注意事项
1. **隐私保护**: 错误数据不包含敏感信息,但建议后端做好脱敏处理
2. **性能影响**: 错误上报使用异步方式,不影响页面性能
3. **网络限制**: 如果网络不可用,错误会失败但不影响应用运行
4. **跨域问题**: 确保接口支持 CORS 或在同一域名下
## iOS 白屏问题排查
通过错误上报,可以收集以下信息来排查 iOS 白屏问题:
1. **早期错误 (phase: 'early')**
- 查看应用初始化前的错误
- 可能是脚本加载或语法错误
2. **用户代理 (ua)**
- 识别具体的 iOS 版本
- 区分不同的 WebView 环境
3. **错误堆栈 (stack)**
- 精确定位错误位置
- 了解错误调用链
4. **URL 信息**
- 判断是否特定页面白屏
- 检查路由参数是否正确
## 实际案例分析
### 案例1: iOS 14.5 微信小程序白屏
```json
{
"type": "error",
"message": "{}",
"stack": null,
"url": "https://tj-h5.hnxdfe.com/h5/#/pages/main/login/login?openid=oosgJj-yr2IrwSmBb3_ERy1hGMos",
"ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.63(0x18003f2f) NetType/4G Language/zh_CN miniProgram/wxece13dd0a5b22c73",
"timestamp": "2026-02-05T11:43:07.707Z",
"phase": "early"
}
```
**问题分析**
- 错误信息为 `{}`,堆栈为 `null`
- 说明错误对象构建时出错,可能是早期错误对象结构异常
- 发生在登录页面URL 中带有 openid 参数
- 环境是 iOS 14.5 + 微信 8.0.63 + 小程序 WebView
**可能原因**
1. 微信小程序 WebView 在早期阶段触发了 error 事件
2. error 事件对象的结构与预期不同
3. 某些初始化脚本在特定环境下执行失败
**已优化**
- 增强了 `buildErrorInfo` 函数,处理更多异常情况
- 添加了对 null/undefined 的特殊处理
- JSON.stringify 失败时的降级处理
- 确保 message 和 stack 永远不会是 null 或空对象
**建议后续观察**
- 检查是否还有类似 `{}``null` 的错误信息
- 统计 iOS 14.5 的错误频率
- 检查登录页面是否是白屏高发页面
- 检查 openid 参数处理是否正常
## 扩展建议
未来可以考虑:
1. 添加错误采样率(避免上报过多)
2. 添加用户反馈功能(用户主动报告问题)
3. 集成第三方错误监控(如 Sentry
4. 添加错误聚合和去重机制