|
|
# 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. 添加错误聚合和去重机制
|