Java - 找到异常的第一个原因

时间:2009-11-24 17:23:33

标签: java oracle exception-handling ora-00001

我需要检查异常是否是由某些数据库问题引起的。我收到一个异常,并检查其原因是否包含“ORA”字符串并返回(类似“ORA-00001”)。这里的问题是我收到的异常嵌套在其他异常中,所以如果我不知道它是否是一个oracle异常,我必须检查该异常的原因,依此类推。 有更清洁的方法吗?有没有办法知道给定异常的第一个原因(深层嵌套异常)?

我目前的代码如下:

private String getErrorOracle(Throwable e){
        final String ORACLE = "ORA";
        if (e.getCause() != null && e.getCause().toString().contains(ORACLE)){
            return e.getCause().toString();
        } else if(e.getCause() != null){
            return getErrorOracle(e.getCause());
        } else {
            return null;
        }
    }

11 个答案:

答案 0 :(得分:81)

为了不重新发明轮子,如果您使用的是Apache Commons Lang,请查看ExceptionUtils.getRootCause()

是否值得为此包括一个图书馆?也许不吧。但是如果你已经在你的类路径中已经有了它,它就在那里,并注意它做了一些“天真”实现可能不会做的事情(例如处理原因链中的循环......呃!)

答案 1 :(得分:16)

如果您已经Guava而非Throwables.getRootCause()来救援。

答案 2 :(得分:14)

只需遍历异常链,直到无故无异常,然后返回该消息,如果你想要最后一个消息。

你的功能只会有第一个原因,如果有的话。

你可能想看看你的包中找到第一个原因,因为实际最深的一个可能是一个oracle异常,这很有帮助,但除非你能看到你在哪里创建问题,否则你会很难修理它。

答案 3 :(得分:3)

可能有点矫枉过正,但我​​认为它更清洁(并且可以重复使用)

interface ThrowablePredicate {
    boolean accept(Throwable t);
}

public OracleErrorThrowablePredicate implements ThrowablePredicate {
    private static final ORA_ERR = "ORA";

    public boolean accept(Throwable t) {
        return t.toString().contains(ORA_ERR);
    }
}


public class CauseFinder {

   private ThrowablePredicate predicate;

   public CauseFinder(ThrowablePredicate predicate) {
      this.predicate = predicate;
   }

   Throwable findCause(Throwable t) {
      Throwable cause = t.getCause();

      return cause == null ? null 
         : predicate.accept(cause) ? cause : findCause(cause)
   }
}


// Your method
private String getErrorOracle(Throwable e){
    return new CauseFinder(new OracleErrorThrowablePredicate()).findCause(e);
}

答案 4 :(得分:2)

我认为oracle抛出的任何错误都将包含在SQLException中(如果错误,有人请纠正我)。一旦访问了SQLException,您就可以调用

getErrorCode用于()           检索此SQLException对象的特定于供应商的异常代码。

让我知道这是否有效,因为我从未尝试过: - )

卡尔

答案 5 :(得分:2)

您可以改进SQLException

的代码检查
import java.sql.SQLException;

private static final String ORACLE = "ORA";

public String doHandle(Throwable t) {
    if (t.getClass().isAssignableFrom(SQLException.class)) {
    SQLException e = (SQLException) t;
    int errCode = e.getErrorCode();
    String state = e.getSQLState();
    String msg = e.getMessage();
    if (msg.contains(ORACLE)) {
        return msg;
        }
    } else {
        if (t.getCause() != null) {
            return this.doHandle(t.getCause());
            }
        }
    return "";
}

另外,我认为在Oracle中“errCode”包含与ORA-nnnn相关的数字

答案 6 :(得分:0)

您可以使用Throwable类中的getStackTrace()。这将为您提供StackTraceElements堆栈。您可以遍历StackTraceElements []来查找“ORA”字符串。

如果您需要一个例子,请告诉我。

答案 7 :(得分:0)

使用核心Java API的单行解决方案:

    try {
        i = 1 / 0; 
    } catch (ArithmeticException e) {
        System.out.println(new ArithmeticException().initCause(e).getCause());
    }

下面的另一个解决方案也可以工作:

    try {
        i = 1 / 0; 
    } catch (ArithmeticException e) {
        System.out.println(new Exception().initCause(e).getCause());
    }

两个都将打印

java.lang.ArithmeticException:/零

答案 8 :(得分:0)

在我的 getRootCause 的 Spring Boot 项目中,IDEA 建议使用 3 个静态导入:

Spring 核心:org.springframework.core.NestedExceptionUtils.getRootCause
杰克逊:com.fasterxml.jackson.databind.util.ClassUtil.getRootCause
番石榴(Swagger 及物)com.google.common.base.Throwables.getRootCause

最聪明的(带周期检查)是 Spring NestedExceptionUtils.getRootCause。 但是,如果您的异常没有任何原因,方法将返回 null。 就我而言,这是错误的,所以我已经完成了:

@NonNull
public static Throwable getRootCause(@NonNull Throwable t) {
    Throwable rootCause = NestedExceptionUtils.getRootCause(t);
    return rootCause != null ? rootCause : t;
}

答案 9 :(得分:-1)

如果抛出的异常总是属于特定类型,例如OracleException,则可以捕获该异常。

例如:

try {

    ...

} catch(OracleException oe) {

    ...

}

这仅适用于抛出特定Oracle异常的情况。我对Oracle知之甚少,所以在尝试之前你可能想知道这是不是正在发生的事情。

答案 10 :(得分:-1)

于28-01-2015 ,我无法解决上述任何解决方案的问题,因此我的建议是使用:

e.getMessage().toString();

Ps:我在Android上使用它。