Можно настроить VS.Net для повреждения, как только любое исключение происходит. Просто выполните свой проект в режиме отладки, и это остановится, как только исключение выдается. Тогда у Вас должна быть лучшая идея того, почему она не поймана.
кроме того, можно вставить некоторый код к выгода все необработанные исключения . Прочитайте ссылку для большего количества информации, но основы являются этими двумя строками.
Application.ThreadException += new ThreadExceptionEventHandler(ThreadExceptionHandler);
// Catch all unhandled exceptions in all threads.
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledExceptionHandler);
Просто пройдитесь по цепочке исключений, пока не дойдете до исключения без причины, а затем просто верните это сообщение, если вы хотите последнюю причину.
Ваша функция получит только первую причину, если она есть.
Возможно, вы захотите найти первую причину в своем пакете, поскольку на самом деле самая глубокая причина может быть исключением из оракула , что полезно, но если вы не видите, где вы создали проблему, вам будет сложно ее исправить.
Чтобы не изобретать колесо заново, если вы используете Apache Commons Lang , посмотрите на ExceptionUtils.getRootCause () .
. Стоит ли для этого включать библиотеку? Может быть нет. Но если он у вас уже есть в пути к классам, он там для вас и обратите внимание, что он делает некоторые вещи, которые «наивная» реализация могла бы не делать (например, иметь дело с циклами в цепочке причин ... тьфу!)
Возможно, это немного избыточно для вашего использования, но я думаю, что он чище (и многоразовый)
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);
}
Я думаю, что любая ошибка, выданная Oracle, будет заключена в SQLException (кто-нибудь, пожалуйста, поправьте меня, если я ошибаюсь). Как только вы получили доступ к SQLException, вы сможете вызвать
getErrorCode () Извлекает код исключения, зависящий от поставщика для этого объекта SQLException.
Сообщите мне, работает ли это, поскольку я никогда не пробовал: -)
Карл
Вы можете улучшить проверку кода для 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
вы можете использовать getStackTrace () из класса Throwable. Это даст вам стек StackTraceElements для работы. Вы можете перебирать StackTraceElements [], чтобы найти строку «ORA».
Дайте мне знать, если вам понадобится пример.
Если генерируемое исключение всегда будет определенного типа, например OracleException, вы можете поймать только это исключение.
Например:
try {
...
} catch(OracleException oe) {
...
}
Это применимо, только если есть выбрасываются определенные исключения Oracle. Я мало что знаю об Oracle, поэтому, прежде чем пытаться это сделать, вы, вероятно, захотите узнать, что же происходит в этом случае.