83

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

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

更新:
感谢大家的友好回复,我想要如下图所示的输出:
在此处输入图像描述
我需要访问 detailMessage字段。
(如果不能让我的问题更清楚,我真的很抱歉。)

谢谢。

4

9 回答 9

110

Apache ExceptionUtils提供以下方法:

Throwable getRootCause(Throwable throwable) 

String getRootCauseMessage(Throwable th) 
于 2013-07-19T13:24:44.197 回答
84

我通常使用下面的实现而不是 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;
}
于 2015-02-17T15:45:50.577 回答
26

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

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

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

于 2016-05-16T00:56:49.340 回答
9

你问这样的事情吗?

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

还是我错过了什么?

于 2013-07-19T13:23:31.083 回答
8

GuavaThrowables提供了以下方法:

Throwable getRootCause(Throwable throwable)

String getStackTraceAsString(Throwable throwable)
于 2017-06-22T12:26:32.730 回答
3

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;
}
于 2015-01-07T08:22:33.780 回答
3
} catch (Exception ex) {
    while (ex.getCause() != null)
        ex = ex.getCause();
    System.out.println("Root cause is " + ex.getMessage());
}

你期待更复杂的事情吗?

于 2013-07-19T13:24:54.173 回答
2

递归:

public static Throwable getRootCause(Throwable e) {
    if (e.getCause() == null) return e;
    return getRootCause(e.getCause());
}
于 2019-03-26T19:07:04.220 回答
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());
}

来源:如何获取任何异常的根异常

于 2018-02-12T18:50:51.167 回答