#java #exception #fortify
#java #исключение #укрепление
Вопрос:
Я получаю проблему fortify как: Плохая обработка ошибок: Throw Inside Наконец, я не создаю исключение внутри блока finally, но все же он показывает эту ошибку. Пожалуйста, найдите код ниже. `
catch( IOException | JSONException | URISyntaxException e)
{
if(instream == null) {
throw new IOException("InputStream not valid");
}
return e.getMessage();
}finally {
if(instream != null ) {
instream.close();
}
if(urlConnection != null ) {
urlConnection.disconnect();
}
}
Комментарии:
1. Пожалуйста, добавьте ваше конкретное исключение и его трассировку стека. И если исключение возникает до вашего опубликованного кода, пожалуйста, добавьте полный код.
2. @Milgo вы, кажется, не понимаете вопроса. Проблема не в исключении или трассировке стека. Это предупреждение linting (анализатор кода, который сообщает о потенциальных ошибках). Смотрите мой ответ.
Ответ №1:
Нет, вы: inStream.close()
можете бросить.
Как правило, «лечение» предупреждения на самом деле ухудшит ваш код. В этом проблема:
ЕСЛИ блок try выдает неперехваченное исключение
В этом случае выполняется блок finally. Допустим, что выполняется блок finally in.close();
. Особенно, если вся причина, по которой мы здесь оказались, заключается в том, что in
он отключился и начал выбрасывать ioeX, это, вероятно, также приведет к ioeX. Любые исключения, выброшенные из блока finally, «перезаписывают» исключение, из-за которого мы оказались здесь, и трассировка стека из этого вызова close гораздо менее полезна.
Так что это плохо.
Мы можем исправить это, обернув in.close()
ваш блок finally в a try { .. } catch (Exception ignore) {}
. Но тогда другой сценарий действительно плох:
ЕСЛИ мы доберемся сюда «нормально»
Возможно, что входной поток работает идеально, а затем, когда вы его закрываете, он выдает. Долгое время общепринятой мудростью было «да какая разница, кому какое дело, я получил свои данные», но это неразумная идея: если закрытие ввода заканчивается выбросом, это, вероятно, означает, что вы на самом деле еще не получили все данные, иначе зачем это было делать? Итак, теперь молчаливое проглатывание любых исключений — плохая идея, и мы хотим ее выбросить.
Не перегибаясь назад, используя логическое значение для отслеживания того, как мы добрались до блока finally, и в зависимости от этого, проглатывая это исключение или нет, невозможно сделать это правильно.
Поскольку это так сложно, try-with-resources на самом деле делает это правильно и генерирует необходимый шаблон.
Таким образом, РЕАЛЬНОЕ решение: если вы закрываете ресурсы в блоке finally, не делайте этого. try (ResourceType r = new ResourceType()) { ... }
Вместо этого используйте синтаксис.
Если вы действительно не можете этого сделать, и вы также не можете заставить его работать, создав оболочку, которая является автоматически закрываемой и, например, ничего не будет делать, если ресурс равен null, тогда вы в основном вынуждены сообщить своему linter прекратить жаловаться на это.