компилятор java говорит, что это исключение никогда не выбрасывается в теле соответствующего оператора try-но оно выбрасывается

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

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

это явно ложно, так как исключение брошено, как я поймал его раньше. Я что-то упускаю?

tia, рубль

5 ответов


это не бросать 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);
}

или просто передать исключение в качестве 2-й аргумент logger, если хорошо настроен, его stacktrace будет напечатан:

} catch (Exception e) {
    logger.error("Caught Exception in login(): " + e.getMessage(), e);
}

обновление в соответствии с вашими комментариями: лучше всего обновить улов следующим образом:

} catch (ClientTransportException e) {
    if (e.getCause() instanceof UnknownHostException) {
        // UHE.
    } else {
        // Other.
    }
}

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


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


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


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


на android я видел это, но на самом деле это проходило как UndeclaredThrowableException. Так что вместо того, чтобы ловить UnknownHostException, Я только что поймал UndeclaredThrowableException.