背景介绍
项目中有使用到 com.github.dreamroute excel-helper 这个工具来辅助 Excel 文件的解析,出错时的代码是这样写的:如下所示(非源代码)
try { excelDTOS = ExcelHelper.importFromFile(ExcelType.XLSX, file, ExcelDTO.class); } catch (Exception e) { log.error("ExcelHelper importFromFile exception msg {}", e.getMessage()); }
因为打印异常信息时,使用了 e.getMessage() 方法,没有将异常信息打印出来。而且本地复现也没有复现出来。所以只能考虑使用 arthas 来协助排查这个问题了。
排查过程
1、线上服务器安装 Arthas。
https://arthas.aliyun.com/doc/install-detail.html
2、使用 watch 命令监控指定方法,打印出异常的堆栈信息,命令如下:
watch com.github.dreamroute.excel.helper.ExcelHelper importFromFile '{params,throwExp}' -e -x 3
再次调用方法,捕获到异常栈信息如下:
已经捕获到异常,并打印出堆栈信息。
3、根据对应的堆栈信息,定位到具体的代码,如下:
代码很简单,从代码中可以很清晰的看到如果没有从 headerInfoMap 中没有获取到指定的 headerInfo ,就会抛这个异常。没有找到只有两种情况:
- headerInfoMap 中保存的信息不对。
- cell 中的 columnIndex 超出的正常的范围导致没有获取到对应 HeaderInfo 。
对于第二种情况,首先去校验了一下上传的 Excel 文件是否有问题,本地测试了一下 Excel 文件,没有任何问题。本地测试也是成功的,所以主观判断,第二种情况的可能性不大。
所以说主要检查第一种情况是否发生,这个时候可以再去看一下该方法的第一行代码
MapheaderInfoMap = processHeaderInfo(rows,cls);
可以看到headerInfoMap是通过processHeaderInfo中获取的。找到processHeaderInfo 的代码,如下所示。
public static MapproceeHeaderInfo(Iteratorrows, Class cls) {
if (rows.hasNext()) {
Row header = rows.next();
return CacheFactory.findHeaderInfo(cls, header);
}
return new HashMap<>(0);
}
public static MapfindHe