Java-компилятор говорит, что это исключение никогда не выбрасывается в тело соответствующего оператора try, но это _is_ throw
У меня есть следующий код:
try {
//jaw-ws service port operation
port.login();
} catch (Exception e) {
logger.error("Caught Exception in login(): " + e.getMessage());
}
Когда вышеуказанное выполняется с неправильным именем хоста, я получаю:
Caught Exception in login(): HTTP transport error: java.net.UnknownHostException: abc
Это правильно и ожидаемо. Я переписал код специально, чтобы поймать UnknownHostException, следующим образом:
import java.net.UnknownHostException;
try {
//jaw-ws service port operation
port.login();
} catch (UnknownHostException uhe) {
//do something specific to unknown host exception
} catch (Exception e) {
logger.error(Caught Exception in login(): " + e.getMessage());
}
Однако, когда я пытаюсь скомпилировать это, я получаю:
[javac] foo.java: exception java.net.UnknownHostException is never thrown in body of corresponding try statement
[javac] } catch (UnknownHostException uhe) {
[javac] ^
Это явно ложно, поскольку исключение выбрасывается, как я его поймал раньше. Что мне здесь не хватает?
ТИА,
рубль
Ответы
Ответ 1
Он не выбрасывает UnknownHostException
. Он просто появляется в сообщении исключения, которое вы действительно поймали. Вероятно, это основная причина исключения, которое вы поймали.
Чтобы определить фактическое исключение, вы должны распечатать немного более подробно. Например.
} catch (Exception e) {
logger.error("Caught Exception in login(): " + e.getClass().getName() + ": " + e.getMessage());
}
или просто используя Throwable#toString()
, который уже включает в себя как тип исключения, так и сообщение:
} catch (Exception e) {
logger.error("Caught Exception in login(): " + e);
}
или просто передать исключение в качестве второго аргумента логгера, если будет правильно настроен его стек:
} catch (Exception e) {
logger.error("Caught Exception in login(): " + e.getMessage(), e);
}
Обновить в соответствии с вашими комментариями: лучше всего обновить улов следующим образом:
} catch (ClientTransportException e) {
if (e.getCause() instanceof UnknownHostException) {
// UHE.
} else {
// Other.
}
}
Вы должны абсолютно не различать на основе сообщения. Это рецепт для проблем с переносимостью. Сообщение является чувствительным субъектом для изменений, которые могут даже быть зависимыми от языка!
Ответ 2
Существуют различные тонкие (или, в некоторых случаях, неподходящие) способы бросить проверенные исключения в ситуациях, когда они явно не объявлены. Некоторые из них перечислены на этой странице.
Ответ 3
Просто мысль, может ли это быть UnknownHostException
в другом пакете?
Ответ 4
e.getMessage() дает вам вывод, указывающий на то, что UnknownHostException происходит где-то, но, возможно, код, стоящий за port.login(), где-то ловится UnknownHostException, бросает другое исключение и указывает в этом сообщении об исключении, что исключение UnknownHostException было исходным исключением (или, возможно, цепочки). Трудно сказать, не зная, какой именно тип исключений попадает в ваш исходный блок catch. Сначала найдите это (возможно, просто сделав e.printStackTrace()), и это должно сказать вам, что вы должны ловить.
Ответ 5
В андроиде я видел это, но на самом деле он проходил как UndeclaredThrowableException
. Поэтому вместо того, чтобы ловить UnknownHostException
, я просто поймал UndeclaredThrowableException
.