Когда это нормально, чтобы поймать RuntimeException



в недавнем проекте я рекомендовал поймать RuntimeException в тестовом коде жгута проводов и зарегистрировать его. Код обрабатывает ряд входных данных из базы данных, и я не хочу, чтобы тест останавливался из-за отказа какого-либо одного входа (нулевые значения, незаконные Аргументы и т. д.). Излишне говорить, что мое предложение вызвало бурную дискуссию.



является ли улавливание любого вида RuntimeException приемлемым? Если да, то каковы другие сценарии, где можно поймать RuntimeExceptions?

629   10  

10 ответов:

вы ловите RuntimeException по той же причине, что вы ловите любое исключение: вы планируете что-то сделать с ним. Возможно, вы можете исправить все, что вызвало исключение. Возможно, вы просто хотите повторно бросить с другим типом исключения.

ловить и игнорировать любое исключение, однако, является крайне плохой практикой.

Если вы не можете исправить RuntimeException, вы не хотите, чтобы поймать его...

...только правда с точки зрения разработчиков....

вы должны поймать все исключения, прежде чем они достигнут до UI и сделать ваш пользователь грустно. Это означает, что на" высшем уровне " вы хотите поймать все, что происходит дальше вниз. Затем вы можете сообщить пользователю, что возникла проблема, и в то же время принять меры для информирования разработчиков, например, отправить из тревожной почты или что-то еще...

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

RuntimeException предназначен для использования при ошибках программиста. Как таковой, он никогда не должен быть пойман. Есть несколько случаев, когда это должно быть:

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

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

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

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

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

лет назад мы написали фреймворк системы управления и объекты агента поймали исключения времени выполнения, зарегистрировали их, если они могли, и продолжили.

Да мы поймали Runtime исключения, включая OutOfMemory в нашем рамочном коде( и принудительно GC, и удивительно, насколько хорошо это поддерживало даже довольно протекающий код.) У нас был код, который делал очень математические вещи, связанные с реальным миром; и время от времени не-число попадало из-за крошечного округления ошибки, и он справился с этим тоже.

поэтому в framework / "не должен выходить" код я думаю, что это может быть оправдано. И когда это работает, это круто.

код был довольно солидным, но он запускал аппаратное обеспечение, а аппаратное обеспечение иногда дает странные ответы.

Он был разработан, чтобы работать без вмешательства человека в течение нескольких месяцев. Он работал очень хорошо в наших тестах.

как часть кода восстановления ошибок, он может прибегнуть к перезагрузке все здание используя способность UPS повернуть в N минутах и повернуть дальше в M минутах.

иногда аппаратные сбои нужно циклически включать:)

Если я помню, последнее средство после неудачного цикла питания было отправкой электронной почты его владельцам, говоря "Я пытался исправить себя, и я не могу; проблема находится в подсистеме XYZ", и включил ссылку, чтобы поднять вызов поддержки обратно к нам.

к сожалению, проект был законсервирован до того, как он смог осознать себя :)>

в моем коде 99% моих исключений являются производными от runtime_exception.

причины, по которым я ловлю исключения:

  • поймать журнал и исправить проблему.
  • поймать журнал и создать более конкретное исключение и бросить
  • поймать журнал и rethrow.
  • поймать журнал и убить операцию (исключение сброса)
    • пользователь/запрос инициировал действие не удается.
      Например, обработчик HTTP-запроса. Я бы предпочел запрошенная операция умирает, а не сбивает службу. (Хотя предпочтительно обработчик имеет достаточно смысла, чтобы вернуть код ошибки 500.)
    • тестовый случай прошел / не прошел с исключением.
    • все исключения не в главном потоке.
      Разрешение исключений для выхода из потока обычно плохо документируется, но обычно вызывает завершение программы (без разматывания стека).

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

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

редактировать 1: Как сказал кдгрегори, ловить и игнорировать-это две разные вещи, как правило, люди против последнего : -)

мы все знаем, что проверенные исключения и RuntimeExceptions есть две категории исключений. Всегда предлагается, что мы обрабатываем (либо try-catch, либо throw) проверенные исключения, потому что они являются условиями программирования, где, к сожалению, программист не может ничего сделать сам по себе; Как FileNotFoundException это не программист, который помещает файлы на диск пользователя, если программа на самом деле пытается прочитать файл 1.txt который должен быть там на f:\ пользователя с заявления:

File f11 = new File("f:\1.txt");
FileInputStream fos = new FileInputStream(f11);

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

позвольте мне также объяснить второй сценарий, с которым понятие RuntimeException будет понятно. Рассмотрим следующее код:

int a = {1,2,3,4,5};
System.out.println(a[9]);

это плохое кодирование, которое генерирует ArrayIndexOutOfBoundsException. Например,RuntimeException. Таким образом, программист не должен фактически обрабатывать исключение, пусть он разбивает программу, а затем исправляет логику.

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

вы ловите RuntimeExceptions (на любом языке: непредвиденные исключения/"все" исключения), когда ваша программа выполняет несколько подзадач, и имеет смысл выполнить все, что вы можете, а не останавливаться на первой неожиданной ситуации. Тестовый набор-прекрасная ситуация для этого - вы хотите знать, какой из все тесты не удалось, не только первый тест. Ключевой характеристикой является то, что каждый тест независим от всех остальных - не имеет значения, был ли предыдущий тест не работает, потому что заказ не имеет значения в любом случае.

Другой распространенной ситуацией является сервер; вы не хотите, чтобы закрыть только потому, что один запрос был искажен таким образом, вы не ожидали. (Если это действительно, действительно важно, чтобы свести к минимуму шансы непоследовательного состояния.)

в любой из этих ситуаций, подходящая вещь, чтобы сделать, это войти / сообщить об исключении и продолжить с остальными задачами.

можно было бы неопределенно обобщить на любое исключение: "уместно поймать" исключение тогда и только тогда, когда есть что-то разумное сделать после ловить его: как ваша программа должна продолжить.

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

Если клиент не может ничего сделать для восстановления из исключения, сделайте его непроверенным исключением.

вот основная линия руководства.

От Java Docs. Пожалуйста, прочтите это Непроверенные Исключения-Полемика

Comments

    Ничего не найдено.