Java-компилятор говорит, что это исключение никогда не выдается в теле соответствующего оператора try - но оно _is_ выбрасывается - PullRequest
15 голосов
/ 26 июля 2010

У меня есть следующий код:

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]                  ^

Это явно неверно, так какисключение брошено, как я поймал это раньше.Что мне здесь не хватает?

тиа, рубль

Ответы [ 5 ]

15 голосов
/ 26 июля 2010

Это не бросает 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.
    }
}

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

1 голос
/ 26 июля 2010

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

0 голосов
/ 30 октября 2016

На андроиде я видел это, но на самом деле это прозвучало как UndeclaredThrowableException.Поэтому вместо того, чтобы поймать UnknownHostException, я просто поймал UndeclaredThrowableException.

0 голосов
/ 26 июля 2010

e.getMessage () дает вам вывод, указывающий, что UnknownHostException где-то происходит, но, возможно, код позади port.login () где-то перехватывает UnknownHostException, выдает другое Exception и указывает в сообщении этого исключения, что UnknownHostException было исходным исключением (или, возможно, цепочки). Трудно сказать, не зная, какой именно тип исключения был пойман в вашем исходном блоке catch. Сначала выясните это (возможно, просто выполнив e.printStackTrace ()), и это должно сказать вам, что вы должны ловить.

0 голосов
/ 26 июля 2010

Просто мысль, может ли это быть UnknownHostException в другой упаковке?

...