Java - найти первую причину исключения
Мне нужно проверить, вызвано ли какое-либо исключение какой-либо проблемой базы данных. Я получаю исключение и проверяю, содержит ли его причину строку "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;
}
}
Ответы
Ответ 1
Просто переходите к цепочке исключений, пока не попадете в исключение без причины, а затем просто вернете это сообщение, если хотите последний.
Ваша функция получит только первую причину, если она есть.
Возможно, вам захочется взглянуть на первую причину в вашем пакете, так как самым глубоким может быть исключение оракула, что полезно, но если вы не видите, где вы создали проблему, вам будет трудно фиксируя его.
Ответ 2
В интересах не изобретать колесо, если вы используете Apache Commons Lang, посмотрите на ExceptionUtils.getRootCause().
Стоит ли включать библиотеку только для этого? Возможно, нет. Но если у вас уже есть это на пути к классу, это для вас, и обратите внимание, что он делает некоторые вещи, которые может быть реализована не наивной (например, с циклами в цепочке причин... ugh!)
Ответ 3
Если вы уже находитесь на Guava, чем Throwables.getRootCause() приходит на помощь.
Ответ 4
Вероятно, немного переборщик для вашего использования, но я думаю, что он более чистый (и многоразовый)
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);
}
Ответ 5
Я думаю, что любая ошибка, создаваемая oracle, будет завернута в SQLException (кто-то, пожалуйста, исправьте меня, если не ошибается). После того, как вы получили доступ к SQLException, вы сможете позвонить
getErrorCode() Извлекает код исключения для поставщика для этого объекта SQLException.
Сообщите мне, если это работает, поскольку я никогда не пробовал: -)
Карл
Ответ 6
Вы можете улучшить проверку кода для 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
Ответ 7
вы можете использовать getStackTrace() из класса Throwable. Это даст вам стек StackTraceElements для работы. Вы можете выполнить итерацию через StackTraceElements [], чтобы найти строку "ORA".Дел >
Сообщите мне, если вам нужен пример.
Ответ 8
Если генерируемое исключение всегда будет иметь определенный тип, например OracleException, вы можете поймать только это исключение.
Например:
try {
...
} catch(OracleException oe) {
...
}
Это применимо только в том случае, если возникают особые исключения Oracle. Я не очень разбираюсь в Oracle, поэтому, прежде чем пытаться это сделать, вы, вероятно, захотите узнать, что происходит.
Ответ 9
28-01-2015, я не могу решить проблему с любым из вышеперечисленных решений, поэтому я рекомендую использовать:
e.getMessage().toString();
Ps: я использую его на android.