第3章 常见报错类型总览

做SDK接入这么多年,我见过最离谱的一次,是对方服务器返回了200,但业务数据全是乱码。你说气不气人?后来发现是网络代理把响应体截了一半。从那以后,我习惯先不看业务逻辑,先把报错类型分类搞清楚。

说实话,SDK报错再怎么千奇百怪,归根结底就五大类。你只要把每一类的根因摸透,排查速度至少快三倍。下面我按出现频率从高到低,挨个拆一遍。

SDK接入报错 — 五大类型 SDK 报错 网络错误 认证失败 参数异常 版本不兼容 权限不足 实际工单统计:网络错误占45%以上,认证失败约25%,参数异常和版本不兼容各占12%,权限不足约6%。 但权限不足的排查成本往往最高,因为它经常和系统策略混在一起。

一、网络错误

网络错误说白了就是「数据没到」。我接触的SDK里,大概有45%的线上报错都跟网络沾边。常见的表现有:

  • 连接超时——SDK请求发出去,对方一直没有回握手ACK
  • 读超时——连接建立成功,但数据响应太慢
  • DNS解析失败——域名配置写错了,或者DNS污染
  • SSL握手失败——证书过期、双向认证没配、TLS版本不匹配

我遇到过最隐蔽的一次:用户在自己机房部署网关,SDK请求正好经过一个老旧代理,代理把HTTP头里的Host字段改掉了,结果服务端校验域名不通过,一直报403。后来我直接在SDK侧打印了curl日志才抓到。

排查建议:先看SDK日志里的HTTP状态码和耗时。如果状态码是0或者负值,基本是网络层问题。抓包对比正常设备和异常设备的网络路径,往往一眼就能定位。

二、认证失败

认证失败常见于AppKey/AppSecret不对,或者签名算法实现有偏差。我习惯把这类问题分成三层:

  1. 凭据层——AK/SK漏填、填错、过期
  2. 签名层——参数排序不一致、拼接格式有误、加解密算法没对齐
  3. 令牌层——access_失效、refresh_没有正确处理

有一次,团队新来的同学把AppSecret复制时多了一个换行符,从IDE直接粘到配置文件里时带上了不可见字符。服务端验签一直失败,排查了整整两天。你想想看,如果当时我让SDK在debug模式下打印签名前的明文字符串,这事十分钟就解决了。

认证失败子类型典型错误码根因占比(我统计过)
AppKey不存在4010135%
签名不匹配4010345%
过期4010515%
权限范围不匹配401075%
注意:很多认证失败的原因其实在服务端日志里就能找到。别只盯着SDK这一侧,带上请求id去找后台同事要服务端日志,省时省力。

三、参数异常

参数异常是典型的「你给了,但给错了」。最常见的是:

  • 必填字段缺失(比如创建订单时没传商品ID)
  • 字段类型不对(数字传成了字符串,或者相反)
  • 枚举值越界(比如用户状态传了100,而合法值只有0和1)
  • 长度超限(昵称写了200个字符,服务端只接受50个)

我记得有一次对接一个支付SDK,接口文档里写金额单位是「分」,但SDK内部偷偷把单位转成了「元」。两边一乘,金额差了一百倍。最后我不得不在SDK初始化时加了一个参数校验拦截器。

说白了,参数异常的排查最依赖文档。我的习惯是:先对照文档检查每个参数的类型、长度、必填性,然后用mock数据逐字段验证。如果SDK提供了strict mode,一定在开发环境打开。

我自己的参数校验checklist:

  • ❏ 必填参数全部传入?
  • ❏ 数值类型是否用了正确的基础类型?(int vs long vs string)
  • ❏ 字符串长度是否在服务端允许范围内?
  • ❏ 枚举值是否在文档定义的集合内?
  • ❏ 日期格式是否与接口文档一致?(ISO8601 / 时间戳 / yyyyMMdd)

四、版本不兼容

版本不兼容是集成SDK时最容易忽略的坑。我见过几种典型场景:

  • SDK版本太老——服务端升级了接口协议,旧SDK还在用老字段
  • 依赖冲突——SDK内部依赖的第三方库(比如OkHttp、Gson)和宿主App的版本不一致,导致NoSuchMethodError
  • 平台版本下限过高——SDK要求Android 8.0以上,而你的App还在支持Android 6.0

嗯,这里要注意:版本不兼容的报错信息往往很迷惑。比如明明代码里调了一个方法,运行时却告诉你「找不到符号」。你第一反应是代码写错了,其实很可能是依赖的jar被宿主项目的旧版本覆盖了。

我以前踩过一个坑:SDK使用Gson 2.8.9,宿主App里有个老模块依赖Gson 2.3.1。运行时优先加载了2.3.1,新版本里的TypeAdapter根本不存在,直接崩了。后来我写了一个依赖检测工具,在SDK初始化时打印所有第三方库的版本号。

五、权限不足

权限不足的报错,通常发生在SDK需要访问系统敏感资源(定位、相机、存储)或者调用服务端受限API时。它的诡异之处在于:

  • 部分厂商的定制ROM有额外的权限管控(比如华为、小米的智能拦截)
  • 动态权限申请如果用户点击「拒绝并不再询问」,后续永远不会弹出授权弹窗
  • 服务端权限校验经常踩到「有权限但角色不对」的坑

有一次我排查一个图片上传SDK的授权问题,用户明明同意了存储权限,但SDK仍然是403。后来发现服务端根据图片内容做了禁黄检测,认为用户没有「上传成人内容」的权限。你想想看,这种业务层权限和系统层权限混在一起,查起来多头疼。

权限不足的排查路径(我总结的):

  1. 先确认系统权限是否在manifest里声明,运行时是否已经获取到
  2. 再检查SDK是否有额外的「应用内权限」概念(比如需要登录后才有写权限)
  3. 最后看服务端返回的403 body里有没有具体的权限名称或scope字段

这五类报错,你只要在日常排查中反复用几次,基本就能形成肌肉记忆。下次再看到报错,别慌,先往这五个框框里套一下,大概率能快速定位方向。