现象
今天测试时发现,在无网情况下,在 try catch 内调用 Log 如下方法打印异常信息,无输出。同样也没有成功写入到本地文件,很奇怪。
public static int e(String tag, String msg, Throwable tr) {
return printlns(LOG_ID_MAIN, ERROR, tag, msg, tr);
}
分析
之后看了下源码,发现系统对于 UnknownHostException 异常做了特殊限制,可能是出于信息安全方面的考虑,不会对此异常的信息进行打印输出。来看下代码:
if (tr != null) {
// This is to reduce the amount of log spew that apps do in the non-error
// condition of the network being unavailable.
Throwable t = tr;
while (t != null) {
if (t instanceof UnknownHostException) {
break;
}
if (t instanceof DeadSystemException) {
lbbw.println("DeadSystemException: The system died; "
+ "earlier logs will point to the root cause");
break;
}
t = t.getCause();
}
if (t == null) {
tr.printStackTrace(lbbw);
}
}
而为何本地文件也没有写入成功呢?这是因为在写入的时候,我调用了 getStackTraceString 方法来获取异常追踪信息,而同样系统也对该方法进行了限制:
Throwable trace = current.getTrace();
if (trace != null) {
// todo:要适配 UnknownHostException
msg = Log.getStackTraceString(trace);
}
再来看下源码,真是奇怪的知识又增加了。所以我们要做好适配,针对UnknownHostException 可以通过输出 e.toString() 来避免这个问题。
public static String getStackTraceString(Throwable tr) {
if (tr == null) {
return "";
}
// This is to reduce the amount of log spew that apps do in the non-error
// condition of the network being unavailable.
Throwable t = tr;
while (t != null) {
if (t instanceof UnknownHostException) {
return "";
}
t = t.getCause();
}
StringWriter sw = new StringWriter();
PrintWriter pw = new FastPrintWriter(sw, false, 256);
tr.printStackTrace(pw);
pw.flush();
return sw.toString();
}