Go to file
hailin 704ee523c9 fix(android): 添加协程全局异常处理器,防止未捕获异常崩溃 [P2]
【架构安全修复 - 防止协程未捕获异常导致应用崩溃】

## 问题背景

协程中的未捕获异常会传播行为:
1. 子协程中的异常会传播到父协程
2. SupervisorJob 虽然防止子协程失败取消其他子协程,但不捕获异常
3. 未处理的异常最终会导致应用崩溃

## 存在的风险

### 场景 1: 后台消息收集失败
- 原问题: messageCollectionJob 中网络异常未捕获
- 后果: 整个 repositoryScope 取消,所有后台任务停止 → 功能完全失效

### 场景 2: 事件订阅异常
- 原问题: sessionEventJob 中解析事件数据异常
- 后果: 事件订阅中断,无法接收后续事件 → 签名/密钥生成卡住

### 场景 3: RPC 调用失败
- 原问题: getBalance 等方法中 JSON 解析失败
- 后果: 应用崩溃 → 用户体验极差

## 修复方案

### 添加 CoroutineExceptionHandler

在 repositoryScope 中配置全局异常处理器:

### 异常分类处理

根据异常类型采取不同策略:
1. CancellationException - 正常的协程取消,仅记录日志
2. 网络异常 (SocketTimeoutException, UnknownHostException, IOException)
   - 记录警告日志
   - 可以触发重连逻辑
3. 状态异常 (IllegalStateException, IllegalArgumentException)
   - 记录错误日志和堆栈
   - 可以重置状态或通知 UI
4. 其他未知异常
   - 记录详细错误信息
   - 防止应用崩溃,保持功能可用

## 修复的崩溃场景

### 场景 1: 网络突然断开时消息收集崩溃
- 原问题: messageCollectionJob 中 grpcClient.routeMessage() 抛出 IOException
- 修复前: 异常传播导致 repositoryScope 取消 → 所有后台任务停止
- 修复后: 异常被 CoroutineExceptionHandler 捕获 → 记录日志,其他任务继续运行

### 场景 2: 服务端返回格式错误导致解析崩溃
- 原问题: JSON 解析失败抛出 JsonSyntaxException
- 修复前: 应用直接崩溃
- 修复后: 异常被捕获,记录错误日志,用户可继续使用其他功能

### 场景 3: partyId 未初始化导致的崩溃
- 原问题: 虽然已添加 requirePartyId() 检查,但如果异常未捕获仍会崩溃
- 修复前: IllegalStateException 导致应用崩溃
- 修复后: 异常被捕获,用户看到错误提示而非应用崩溃

### 场景 4: 并发竞态条件导致的状态异常
- 原问题: 快速切换页面时状态不一致抛出 IllegalStateException
- 修复前: 应用崩溃,用户丢失所有未保存数据
- 修复后: 异常被捕获,状态可以恢复,功能继续可用

## 影响范围

### 修改的代码位置
- TssRepository.kt - 添加 coroutineExceptionHandler
- repositoryScope 配置 - 添加异常处理器到 CoroutineScope

### 行为变化
- BEFORE: 协程中未捕获异常导致应用崩溃
- AFTER: 异常被捕获并记录,应用继续运行

### 日志增强
所有未捕获异常都会记录:
- 异常类型和消息
- 协程上下文信息
- 完整堆栈跟踪
- 根据异常类型的分类标签

## 测试验证

编译状态:  BUILD SUCCESSFUL in 42s
- 无编译错误
- 仅有警告 (unused parameters),不影响功能

## 最佳实践

这个修复符合 Kotlin 协程最佳实践:
1. SupervisorJob - 子协程隔离
2. CoroutineExceptionHandler - 全局异常捕获
3. 明确的异常分类处理
4. 详细的日志记录

## 注意事项

1. CoroutineExceptionHandler 仅捕获未处理的异常
   - 已在 try-catch 中捕获的异常不会触发
   - 这是最后一道防线,不应替代局部异常处理

2. CancellationException 不应被捕获
   - 它是协程取消的正常机制
   - 在 handler 中识别并忽略

3. 重要操作仍应使用 try-catch
   - 关键路径(签名、密钥生成)应保留局部 try-catch
   - 这样可以提供更精确的错误处理和恢复

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-26 21:51:37 -08:00
.claude fix(android): 使用 Kavascan Etherscan API 同步交易记录 2026-01-26 08:51:40 -08:00
backend fix(android): 添加协程全局异常处理器,防止未捕获异常崩溃 [P2] 2026-01-26 21:51:37 -08:00
contracts feat(blockchain): 部署 eUSDT 和 fUSDT 代币合约 2026-01-19 05:30:25 -08:00
docs docs: 添加 RWADurian 2.0 部署与运维成本方案 2026-01-22 03:29:51 -08:00
frontend feat(batch-mining): 动态获取批量补发计算起始日期 2026-01-23 02:01:40 -08:00
kubernetes . 2025-11-25 10:29:24 +08:00
scripts fix(snapshot): 修改 Services PostgreSQL 用户名为 rwa_user 2026-01-08 09:05:22 -08:00
tests . 2025-11-25 10:29:24 +08:00
.gitignore feat(mining-ecosystem): 添加挖矿生态系统完整微服务与前端 2026-01-10 17:45:46 -08:00
README.md first commit 2025-11-23 21:21:44 -08:00
SEED01-qrcode.png fix: 短信超时返回成功状态避免前端报错 2025-12-21 20:55:31 -08:00
STKAITI.TTF feat(mobile-app): 添加合同签署 API 详细调试日志 2025-12-25 03:14:10 -08:00
contract.docx feat(kyc): 实名认证前检查手机号验证状态 2025-12-24 21:00:53 -08:00
docker-compose.yml first commit 2025-11-23 21:21:44 -08:00
挖矿.xlsx feat(contribution): 添加系统账户算力来源类型字段 2026-01-21 04:23:50 -08:00
榴莲皇后数据.xlsx fix(mobile-app): 修复多账号切换后账号列表只显示一个的问题 2025-12-27 11:12:50 -08:00
联合种植协议董事长_release_form.pdf fix(reporting-service): add /api/v1 prefix to wallet and reward service API calls 2026-01-04 23:18:10 -08:00

README.md