如何通过Exception getCause()循环查找具有详细消息的根本原因

时间:2013-07-19 13:20:56

标签: java exception plsql

我试图在hibernate中调用saveOrUpdate()来保存数据。由于列具有唯一索引,因此当我通过Eclipse调试器查看时,它会抛出ConstraintViolationException

由于在将数据插入表格时,根本原因可能因异常而异 我想知道,如何循环/遍历getCause()以检查异常及其消息的根本原因是什么。

更新:
谢谢大家的回复,我想要的输出如下图所示:
enter image description here
我需要访问 detailMessage 字段 (我真的很抱歉如果不能让我的问题更清楚。)

感谢。

9 个答案:

答案 0 :(得分:78)

Apache ExceptionUtils提供以下方法:

Throwable getRootCause(Throwable throwable) 

以及

String getRootCauseMessage(Throwable th) 

答案 1 :(得分:53)

我通常使用下面的实现而不是Apache的实现。

除了复杂性之外,Apache的实现在没有找到原因时返回null,这迫使我执行额外的null检查。

通常在查找异常的根/原因时我已经有一个非空的异常开始,这对于所有预期的建议是导致失败的原因,如果更深层的原因不能被发现。

Throwable getCause(Throwable e) {
    Throwable cause = null; 
    Throwable result = e;

    while(null != (cause = result.getCause())  && (result != cause) ) {
        result = cause;
    }
    return result;
}

答案 2 :(得分:16)

使用java 8 Stream API,可以通过以下方式实现:

Optional<Throwable> rootCause = Stream.iterate(exception, Throwable::getCause)
                                      .filter(element -> element.getCause() == null)
                                      .findFirst();

请注意,此代码不能免除异常原因循环,因此应在生产中避免使用。

答案 3 :(得分:8)

你在问这样的事吗?

Throwable cause = originalException;
while(cause.getCause() != null && cause.getCause() != cause) {
    cause = cause.getCause();
}

或者我错过了什么?

答案 4 :(得分:7)

Guava's Throwables提供以下方法:

Throwable getRootCause(Throwable throwable)

以及

String getStackTraceAsString(Throwable throwable)

答案 5 :(得分:3)

} catch (Exception ex) {
    while (ex.getCause() != null)
        ex = ex.getCause();
    System.out.println("Root cause is " + ex.getMessage());
}

您是否期待更复杂的事情?

答案 6 :(得分:2)

APACHE;实现如下。

重点是 list.contains(throwable)== false

public static Throwable getRootCause(final Throwable throwable) {
    final List<Throwable> list = getThrowableList(throwable);
    return list.size() < 2 ? null : (Throwable)list.get(list.size() - 1);
}

public static List<Throwable> getThrowableList(Throwable throwable) {
    final List<Throwable> list = new ArrayList<Throwable>();
    while (throwable != null && list.contains(throwable) == false) {
        list.add(throwable);
        throwable = ExceptionUtils.getCause(throwable);
    }
    return list;
}

答案 7 :(得分:2)

试试这个,你可以把这个函数放在一个Util类中:

public static Throwable getRootException(Throwable exception){
 Throwable rootException=exception;
 while(rootException.getCause()!=null){
  rootException = rootException.getCause();
 }
 return rootException;
}

使用示例:

catch(MyException e){
  System.out.println(getRootException(e).getLocalizedMessage());
}

来源:How to get the root exception of any exception

答案 8 :(得分:0)

递归:

public static Throwable getRootCause(Throwable e) {
    if (e.getCause() == null) return e;
    return getRootCause(e.getCause());
}