我需要检查异常是否是由某些数据库问题引起的。我收到一个异常,并检查其原因是否包含“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;
}
}
答案 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上使用它。