Подтвердить что ты не робот

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;
        }
    }
4b9b3361

Ответ 1

Просто переходите к цепочке исключений, пока не попадете в исключение без причины, а затем просто вернете это сообщение, если хотите последний.

Ваша функция получит только первую причину, если она есть.

Возможно, вам захочется взглянуть на первую причину в вашем пакете, так как самым глубоким может быть исключение оракула, что полезно, но если вы не видите, где вы создали проблему, вам будет трудно фиксируя его.

Ответ 2

В интересах не изобретать колесо, если вы используете Apache Commons Lang, посмотрите на ExceptionUtils.getRootCause().

Стоит ли включать библиотеку только для этого? Возможно, нет. Но если у вас уже есть это на пути к классу, это для вас, и обратите внимание, что он делает некоторые вещи, которые может быть реализована не наивной (например, с циклами в цепочке причин... ugh!)

Ответ 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.