一、先区分错误发生在哪一层
HTTP错误和短信最终失败不是同一类问题。HTTP 401通常表示认证失败,HTTP 429可能表示请求过快;而API已成功接收后,仍可能在运营商阶段返回号码无效、设备不可达或内容拒绝。
API层鉴权、权限、参数、格式和限流。
平台层余额、模板、国家配置和通道路由。
运营商层号码状态、内容过滤、网络和当地规则。
设备层关机、无信号、存储或用户设置。
二、常见错误分类表
说明:下表使用通用错误名称帮助分类,不代表TextPulse或其他平台的固定编号。实际处理应以接口文档和原始错误码为准。
| 通用错误 | 含义 | 是否建议重试 | 处理方向 |
|---|---|---|---|
| AUTH_FAILED | 密钥错误、过期或权限不足 | 否 | 检查密钥、环境和权限 |
| INVALID_REQUEST | 字段缺失、格式错误 | 否 | 修正请求结构和必填字段 |
| INVALID_NUMBER | 号码格式、国家码或长度错误 | 否 | 标准化为正确国际格式 |
| TEMPLATE_REJECTED | 模板未批准或变量不符合规则 | 否 | 检查模板和实际内容 |
| RATE_LIMITED | 请求速度超过允许范围 | 延迟后可以 | 队列、退避和并发控制 |
| INSUFFICIENT_BALANCE | 余额或信用额度不足 | 充值后可以 | 检查账户和费用告警 |
| ROUTE_UNAVAILABLE | 目标国家或通道暂时不可用 | 通常可以 | 切换备用路由或稍后重试 |
| CARRIER_REJECTED | 运营商拒绝内容、身份或流量 | 视原因 | 检查Sender ID、内容和当地规则 |
| HANDSET_UNREACHABLE | 设备离线、无信号或暂不可达 | 有限重试 | 设置有效期和最大次数 |
| MESSAGE_EXPIRED | 在有效期内未完成发送 | 通常否 | 判断业务是否仍有价值 |
三、哪些错误可以重试?
重试前必须判断错误是否具有临时性。网络超时、平台临时繁忙、限流和短暂路由不可用可以采用指数退避;号码无效、认证失败、模板拒绝和用户退订通常不应重试。
| 类别 | 建议 |
|---|---|
| 永久错误 | 立即停止,修正数据或配置后重新创建请求 |
| 临时错误 | 有限次数、递增间隔并加入随机抖动 |
| 状态未知 | 先使用幂等键或查询接口确认原请求状态 |
| 业务已过期 | 即使技术上可重试,也应停止发送 |
验证码和预约提醒具有明确有效期。消息失去业务价值后继续重试,只会增加费用和用户困扰。
四、标准排查流程
- 确认错误发生在同步API响应还是异步状态回执。
- 保存HTTP状态、平台代码、运营商代码和原始描述。
- 用message ID和业务ID查找完整请求时间线。
- 检查号码国际格式、目标国家和运营商。
- 核对Sender ID、模板、变量、链接和短信分段。
- 按国家、通道和时间检查是否为批量异常。
- 只有确定为临时错误后才执行有限重试。
排查单条短信时要结合相同国家和模板的其他消息。如果同一时间大量失败,通常更可能是通道、运营商或配置问题;若只有单个号码失败,则优先检查号码和设备状态。
五、日志必须保存哪些信息?
{
"request_id": "req_01J...",
"business_id": "otp_login_001",
"message_id": "msg_01J...",
"country": "目标国家",
"provider": "route_a",
"http_status": 202,
"provider_code": "原始错误码",
"normalized_error": "RATE_LIMITED",
"retryable": true,
"attempt": 2,
"occurred_at": "2026-07-16T06:50:00Z"
}
日志中不要保存完整API密钥和不必要的敏感信息。手机号应掩码展示,并限制原始数据访问权限。
六、错误监控和告警
错误率按国家、运营商和模板拆分
可重试率发现平台或路由临时异常
无效号码率评估号码数据质量
未知错误率推动补充映射和文档
告警应关注“相对于正常水平的变化”,而不是仅设置固定数量。低流量国家的少量失败也可能意味着100%异常;高流量业务则更适合使用比例和时间窗口。
七、常见错误处理误区
- 不要把所有失败都自动重试。
- 不要只保存中文描述而丢弃原始错误码。
- 不要把API提交成功计为最终送达。
- 不要使用同一错误策略处理OTP和营销短信。
- 不要在未知状态下直接再次发送同一业务消息。
- 不要忽略国家、运营商、模板和Sender ID维度。