线上数据异常的崩溃,最大的关键是还原线上数据
最新版本,线上报了一个崩溃,崩溃堆栈如下
Caused by: java.util.NoSuchElementException: Collection contains no element matching the predicate.
at b.a.a.c.e.o1.m(ProductModelSelectDialog.kt:12)
at b.a.a.c.e.o1$c.b(ProductModelSelectDialog.kt:20)
at b.a.a.b.u.a.onGlobalLayout(lambda:14)
at android.view.ViewTreeObserver.dispatchOnGlobalLayout(ViewTreeObserver.java:1066)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3156)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2112)
很显然,这个是混淆后的崩溃,我们用对应的mapping文件排查,定位到了异常的代码如下
fun SkuSpecInfo.getFinalLadderPrice(): Int {
if (hasLadderPrice()) {
val number = this.number
//ladderPriceList.first方法报错
return this.ladderPriceList.first {
number >= it.orderMinCount && number <= it.orderMaxCount
}.singlePrice.toFloat().times(100).toInt()
} else {
return this.finalShowPrice.toFloat().times(100).toInt()
}
}
报的错误是Collection contains no element matching the predicate
,说明用ladderPriceList.first
方法,返回的结果是null而导致的崩溃
做了下前后的代码排查,正常情况下是不会出现这个情况的,于是怀疑是接口返回的数据异常
崩溃的时候,是不会上报崩溃时候的数据的,通过代码,可以知道崩溃的是页面的商详页,所以需要定位到具体是浏览哪个商品崩溃了
//自定义事件,同时有上报页面信息
pageName : com.ygp.mro.app.detail.DetailActivity
//还有上报用户的ID
userInfo : 5fb735486f59ea61519ee198
崩溃SDK,我们同时会上报用户ID跟最后浏览的页面,通过ID,可以知道是具体哪个用户的崩溃,然后在神策统计后台,查看该用户的统计数据
神策统计数据,支持SQL查询数据,可以查到该用户所有的统计行为
select * from events where distinct_id = '5fb735486f59ea61519ee198' order by time desc;
distinct_id
就是神策里面的用户id,event
代表用户数据统计表
结果非常多,密密麻麻,难以定位,而且也上报了该用户在小程序上的统计数据了(我们小程序数据跟app数据是一起的),对SQL做了精简,只展示详情页的统计数据、只展示Android端的、只展示我们需要的字段
select product_name,spu_id,time from events where distinct_id = '5fb735486f59ea61519ee198' and event = 'ProductDetail' and $lib = 'Android' order by time desc;
已知崩溃的时间是2021-09-13 09:38:13
,查找对应崩溃时间的上报记录
定位到了跟崩溃吻合的上报事件,并且也有上报商品的id,所以知道了具体哪个商品导致的崩溃了
知道某个商品有异常后,模拟请求该商品数据,发现该商品返回的阶梯价逻辑上不合理,最大购买数量超过了跟阶梯价最大量
问题得以定位,接下来跟后端伙伴反馈该问题,等后端修复上线后,可以线上直接修复该问题,不需要发版