问题描述:
项目中使用了微信登录,有用户反映微信登录错误,这极大的影响了用户体验。
情况紧急,但这类问题很难复现,想获取相关log信息又需要重新发版。幸好,我偶然在自己的手机上复现了bug,遂立即开始排查解决问题。
解决问题后,感觉这次解决过程还是比较典型的,所以记录下来抛砖引玉吧。
问题排查过程:
手机连接adb
这本来不应该是一个问题,开发环境安装正确的情况下,用usb连接手机和PC即可。
但可惜我的手机叫魅族,默认是连不上的。解决方法这里不过多阐述,请查看下面引用文章。按照文章操作后依然无效的,尝试重启设备,包括PC和手机,一般都可以解决。
部分手机无法连接adb问题的解决方法。
MX4 连接adb问题解决
Mac OS X 下部分Android手机无法连接adb问题之解决方案
排查log信息
手机连接adb后,可以在logcat中看到log,并且包括手机连接到adb之前一定时间内的log,所以出错后再连接adb也是可行的。
筛选后找到错误相关信息,发现当获取微信平台信息时报错,返回错误码42001。
根据log信息,查询错误原因
- 通过查询关键词「微信 42001」,找到微信的开发者文档全局返回码说明
42001:access_token超时,请检查access_token的有效期,请参考基础支持-获取access_token中,对access_token的详细机制说明
- 现在已经初步知道原因了,继续查看access_token的文档,进一步了解原因。
access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。access_token的存储至少要保留512个字符空间。access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。
分析原因
已知access_token存在有效期,过期后失效。而当获取微信平台信息时报错,提示access_token有效期超时。
所以错误原因非常明显,我在access_token过期后,继续用过期的access_token去请求平台信息,被微信拒绝。
程序之前的逻辑是,先判断平台是否已授权,如果已授权,则直接使用授权去获取平台信息。伪代码如下:
if 已授权
使用已有授权去获取平台信息
else
取得新的授权,然后获取平台信息
这里没有判断授权是否过期,可能平台已授权但是授权过期,导致了错误的发生。
解决问题
增加授权过期判断,在授权过期后去获取新的授权,即可解决问题。
项目是使用友盟的社会化分享组件来实现相关功能的 。之前判断平台是否已授权,是使用友盟的辅助类 OauthHelper
的isAuthenticated()
方法,修改为使用isAuthenticatedAndTokenNotExpired()
方法,增加过期判断。
修改后的伪代码如下,打包测试,问题解决。
if 已授权 and 授权未过期
使用已有授权去获取平台信息
else
取得新的授权,然后获取平台信息
反思
问题到这里虽然解决了,但解决方式却亟待改进。等用户反馈再处理问题,是亡羊补牢,为时已晚。而自己复现问题,更是属于偶然。应该将类似错误信息上传服务器,以便及时排查解决。
这里使用友盟统计分析的错误统计功能来实现,当登录报错时调用MobclickAgent.reportError(Context context, String error)
将错误信息报告服务器。相关代码如下:
// 请求平台信息
mController.getPlatformInfo(mContext, platform, new UMDataListener() {
@Override
public void onComplete(int status, Map<String, Object> info) {
if (status == 200 && info != null) {
// 请求成功,开始登陆
} else {
// 请求失败,将错误信息报告服务器
String error = String.format("get platform info error, platform %s, status %d", platform, status);
MobclickAgent.reportError(mContext, error);
}
}
});