Skip to content

错误处理篇

定义统一的错误处理架构和用户体验规范


错误分类体系

一级分类

类别前缀说明用户可恢复
网络错误NET_网络连接问题是(重试)
链错误CHAIN_区块链交互问题部分
验证错误VALID_输入验证失败是(修正输入)
认证错误AUTH_身份认证问题是(重新认证)
存储错误STORE_本地存储问题部分
系统错误SYS_系统级异常

错误码目录

NET_ 网络错误

错误码名称用户消息恢复方式
NET_001NetworkOffline网络已断开检查网络后重试
NET_002RequestTimeout请求超时自动重试
NET_003ServerUnavailable服务暂时不可用稍后重试
NET_004RateLimited请求过于频繁等待后重试
NET_005InvalidResponse服务器响应异常重试或联系支持

CHAIN_ 链错误

错误码名称用户消息恢复方式
CHAIN_001InsufficientBalance余额不足充值后重试
CHAIN_002InsufficientGasGas 费不足增加 Gas 或充值
CHAIN_003NonceConflict交易序号冲突重新获取 nonce
CHAIN_004TransactionRejected交易被拒绝检查交易参数
CHAIN_005ContractError合约执行失败检查合约调用
CHAIN_006ChainNotSupported不支持此链切换到支持的链
CHAIN_007NodeUnavailable节点不可用自动切换备用节点
CHAIN_008TransactionDropped交易已被丢弃重新发起交易
CHAIN_009GasPriceTooLowGas 价格过低提高 Gas 价格
CHAIN_010InvalidAddress地址格式无效检查收款地址

VALID_ 验证错误

错误码名称用户消息恢复方式
VALID_001RequiredField请填写此字段填写必填项
VALID_002InvalidFormat格式不正确按提示修正
VALID_003AmountTooSmall金额过小增加金额
VALID_004AmountTooLarge金额超出限制减少金额
VALID_005InvalidMnemonic助记词无效检查助记词
VALID_006PatternMismatch两次图案不一致重新绘制
VALID_007PatternTooSimple图案连接点不足连接更多点
VALID_008InvalidQRCode无法识别二维码重新扫描

AUTH_ 认证错误

错误码名称用户消息恢复方式
AUTH_001WrongPattern图案错误重新绘制
AUTH_002BiometricFailed生物识别失败使用图案锁
AUTH_003BiometricNotAvailable生物识别不可用使用图案锁
AUTH_004TooManyAttempts尝试次数过多等待解锁
AUTH_005SessionExpired会话已过期重新认证
AUTH_006AuthorizationDenied授权被拒绝重新请求授权

STORE_ 存储错误

错误码名称用户消息恢复方式
STORE_001StorageFull存储空间不足清理空间
STORE_002DataCorrupted数据已损坏重新导入钱包
STORE_003DecryptionFailed解密失败检查图案
STORE_004WalletNotFound钱包不存在创建或导入
STORE_005MigrationFailed数据迁移失败联系支持

SYS_ 系统错误

错误码名称用户消息恢复方式
SYS_001UnknownError发生未知错误重试或联系支持
SYS_002CryptoNotSupported加密功能不可用升级浏览器
SYS_003OutOfMemory内存不足关闭其他应用
SYS_004FeatureNotSupported功能暂不支持等待更新

错误数据结构

AppError 基础结构

AppError {
  code: string           // 错误码 (如 "CHAIN_001")
  name: string           // 错误名称
  message: string        // 开发者消息(英文)
  userMessage: string    // 用户消息(多语言 key)
  severity: Severity     // 严重程度
  recoverable: boolean   // 是否可恢复
  retryable: boolean     // 是否可重试
  context?: object       // 上下文信息
  cause?: Error          // 原始错误
  timestamp: number      // 发生时间
}

Severity = 'info' | 'warning' | 'error' | 'critical'

错误上下文

ErrorContext {
  // 操作上下文
  operation: string      // 操作名称
  chainId?: string       // 链 ID
  address?: string       // 相关地址
  txHash?: string        // 交易哈希
  
  // 请求上下文
  requestId?: string     // 请求 ID
  endpoint?: string      // API 端点
  
  // 设备上下文
  platform: string       // 平台
  version: string        // 应用版本
}

错误处理层级

处理架构

┌─────────────────────────────────────────────────────────┐
│                    UI Layer                              │
│            显示用户友好的错误消息                          │
├─────────────────────────────────────────────────────────┤
│                Application Layer                         │
│          决定重试/降级/上报策略                            │
├─────────────────────────────────────────────────────────┤
│                  Service Layer                           │
│            转换为 AppError,添加上下文                     │
├─────────────────────────────────────────────────────────┤
│                 Provider Layer                           │
│              捕获原始错误                                 │
└─────────────────────────────────────────────────────────┘

各层职责

层级职责输出
Provider捕获原始异常原始 Error
Service转换、分类、添加上下文AppError
Application决定处理策略处理决策
UI展示给用户用户界面

错误恢复策略

自动重试

RetryConfig {
  maxAttempts: number    // 最大重试次数
  baseDelay: number      // 基础延迟 (ms)
  maxDelay: number       // 最大延迟 (ms)
  backoffFactor: number  // 退避系数
  retryableErrors: string[]  // 可重试的错误码
}

默认配置:

参数
maxAttempts3
baseDelay1000ms
maxDelay30000ms
backoffFactor2

可重试错误码:

  • NET_002 (RequestTimeout)
  • NET_003 (ServerUnavailable)
  • CHAIN_007 (NodeUnavailable)

降级策略

错误降级方案
主节点不可用切换备用节点
实时数据不可用显示缓存数据
生物识别失败回退图案锁认证
WebSocket 断开降级轮询

用户干预

需要用户干预的情况:

情况用户操作
余额不足充值
图案错误重新绘制
授权被拒重新授权
数据损坏重新导入钱包

错误 UI 规范

Toast 提示(轻量级)

适用:可自动恢复的临时错误

┌─────────────────────────────────────┐
│ ⚠️ 网络连接不稳定,正在重试...        │
└─────────────────────────────────────┘

规范:

  • 自动消失(3-5 秒)
  • 不阻塞用户操作
  • 简短消息

内联错误(表单级)

适用:验证错误

┌─────────────────────────────────────┐
│ 收款地址                             │
│ ┌─────────────────────────────────┐ │
│ │ 0xinvalid...                    │ │
│ └─────────────────────────────────┘ │
│ ❌ 地址格式无效                      │
└─────────────────────────────────────┘

规范:

  • 紧邻出错字段
  • 红色文字 + 图标
  • 具体说明错误原因

对话框(阻塞级)

适用:需要用户决策的错误

┌─────────────────────────────────────┐
│              交易失败                │
├─────────────────────────────────────┤
│                                     │
│  Gas 价格过低,交易未被确认。         │
│                                     │
│  建议操作:                          │
│  • 提高 Gas 价格重新发送             │
│  • 取消此交易                        │
│                                     │
├─────────────────────────────────────┤
│  [取消]              [重新发送]      │
└─────────────────────────────────────┘

规范:

  • 清晰的错误说明
  • 提供解决方案
  • 明确的操作按钮

全屏错误页(严重级)

适用:系统级错误、无法恢复的错误

┌─────────────────────────────────────┐
│                                     │
│              😵                     │
│                                     │
│        出了点问题                    │
│                                     │
│   应用遇到了意外错误。               │
│   我们已记录此问题。                 │
│                                     │
│   错误代码: SYS_001                 │
│                                     │
│        [重新启动]                   │
│        [联系支持]                   │
│                                     │
└─────────────────────────────────────┘

错误日志规范

日志级别

级别用途上报
DEBUG调试信息
INFO一般信息
WARN警告,已处理可选
ERROR错误,需关注
FATAL严重错误立即上报

日志结构

ErrorLog {
  level: LogLevel
  error: AppError
  context: ErrorContext
  stack?: string
  userAgent: string
  timestamp: number
}

敏感信息过滤

MUST NOT 记录以下信息:

  • 助记词
  • 私钥
  • 图案锁
  • 完整地址(仅记录前 6 + 后 4 位)

错误上报规范

上报条件

错误级别上报时机
info/warning-
error (可恢复)聚合上报每 5 分钟
error (不可恢复)即时上报立即
fatal即时上报立即

上报数据

ErrorReport {
  errors: ErrorLog[]
  sessionId: string
  deviceInfo: DeviceInfo
  appVersion: string
}

用户隐私

  • MUST 脱敏后再上报
  • MUST 允许用户关闭错误上报
  • SHOULD 上报前显示上报内容

测试要求

错误场景覆盖

场景测试点
网络断开显示离线提示
请求超时自动重试
余额不足禁用发送 + 提示
图案错误显示错误动画 + 清空
节点不可用自动切换

错误恢复测试

  • 重试后成功
  • 降级后可用
  • 用户干预后恢复

本章小结

  • 统一的错误码体系,便于追踪和处理
  • 分层处理:捕获 → 转换 → 决策 → 展示
  • 自动恢复优先,必要时引导用户
  • 错误 UI 分级:Toast → 内联 → 对话框 → 全屏
  • 完善的日志和上报机制

Released under the MIT License.