【Java】获取有效的异常调用堆栈信息

项目中,可能会遇到虽然知道发生了异常,但是不知道异常是什么,由于调用栈信息不全,从日志上看不出具体问题;主要原因是异常调用栈太深,导致异常信息被截断。

下面这个方法可以获取根异常,将中间的非主要异常过滤掉。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**  
* 获取根异常,防止调用链太长,导致有效信息被截断
*/
public static Throwable getRootThrowable(Throwable e) {
if (Objects.isNull(e)) {
return null;
}

Throwable lastCause = e;
Throwable currentCause = e.getCause();
while (Objects.nonNull(currentCause)) {
lastCause = currentCause;
currentCause = currentCause.getCause();
}

return lastCause;
}

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
@Slf4j  
public class ThrowableTestDemo {
public static void main(String[] args) {
test();
}

private static void test() {
try {
try {
try {
try {
try {
int i = 1 / 0;
} catch (Exception e) {
throw new RuntimeException(e);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
} catch (Exception e) {
log.warn("处理前:", e);
System.out.println("=======>");
log.warn("处理后:", getRootThrowable(e));
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
10:38:13.122 [main] WARN com.coocaa.media.sync.ThrowableTestDemo - 处理前:
java.lang.RuntimeException: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.ArithmeticException: / by zero
at com.coocaa.media.sync.ThrowableTestDemo.test(ThrowableTestDemo.java:36)
at com.coocaa.media.sync.ThrowableTestDemo.main(ThrowableTestDemo.java:15)
Caused by: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.ArithmeticException: / by zero
at com.coocaa.media.sync.ThrowableTestDemo.test(ThrowableTestDemo.java:33)
... 1 common frames omitted
Caused by: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.ArithmeticException: / by zero
at com.coocaa.media.sync.ThrowableTestDemo.test(ThrowableTestDemo.java:30)
... 1 common frames omitted
Caused by: java.lang.RuntimeException: java.lang.ArithmeticException: / by zero
at com.coocaa.media.sync.ThrowableTestDemo.test(ThrowableTestDemo.java:27)
... 1 common frames omitted
Caused by: java.lang.ArithmeticException: / by zero
at com.coocaa.media.sync.ThrowableTestDemo.test(ThrowableTestDemo.java:25)
... 1 common frames omitted

=======>
10:38:13.124 [main] WARN com.coocaa.media.sync.ThrowableTestDemo - 处理后:
java.lang.ArithmeticException: / by zero
at com.coocaa.media.sync.ThrowableTestDemo.test(ThrowableTestDemo.java:25)
at com.coocaa.media.sync.ThrowableTestDemo.main(ThrowableTestDemo.java:15)