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

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

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

ТИА, рубль

4b9b3361

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