Когда это хорошо для ловли RuntimeException

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

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

65
задан james.garriss 11 March 2016 в 14:08
поделиться

8 ответов

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

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

.
94
ответ дан 24 November 2019 в 15:17
поделиться

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

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

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

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

.
33
ответ дан 24 November 2019 в 15:17
поделиться

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

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

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

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

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

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

15
ответ дан 24 November 2019 в 15:17
поделиться

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

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

  • Catch Log and Fix problem.
  • Catch Log and Generate a more specific exception and throw
  • Catch Log and rethrow.
  • Catch Log and Kill operation (disard exception).
  • Catch Log and Kill operation (disard exception)
    • Инициированное пользователем/запросом действие не срабатывает.
      Например, обработчик HTTP-запросов. Я бы предпочёл, чтобы запрашиваемая операция умерла, а не привела бы к падению сервиса. (Хотя желательно, чтобы обработчик имел достаточно смысла, чтобы вернуть код 500 ошибки.)
    • Test case passed/failed with a exception.
    • All exceptions not in the main thread.
      Разрешение исключениям экранировать поток обычно плохо документировано, но обычно приводит к завершению программы (без разматывания стека).
7
ответ дан 24 November 2019 в 15:17
поделиться

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

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

Edit 1: Как сказал kdgregory, ловля и игнорирование - две разные вещи, в общем, люди против последнего :-)

.
4
ответ дан 24 November 2019 в 15:17
поделиться

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

2
ответ дан 24 November 2019 в 15:17
поделиться

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

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

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

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

.
1
ответ дан 24 November 2019 в 15:17
поделиться

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

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

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

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

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

Как часть кода восстановления после ошибки, он может прибегнуть к перезагрузке всего здания, используя способность ИБП отключаться за N минут и включаться за M минут.

Иногда при аппаратных сбоях необходимо выключить и снова включить питание :)

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

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

7
ответ дан 24 November 2019 в 15:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: