Это плохая практика - ловить Throwable
?
Например что-то вроде этого:
try {
// Some code
} catch(Throwable e) {
// handle the exception
}
Это плохая практика или мы должны быть как можно более конкретными?
java
exception-handling
throwable
Ktulinho
источник
источник
Ответы:
Вы должны быть максимально конкретными. Иначе таким образом могут исчезнуть непредвиденные ошибки.
Кроме того,
Throwable
обложкиError
тоже, а это обычно не точка возврата . Вы не хотите ловить / обрабатывать это, вы хотите, чтобы ваша программа немедленно умерла, чтобы вы могли ее исправить.источник
Это плохая идея. На самом деле, даже поимка
Exception
- плохая идея. Рассмотрим пример:Теперь предположим, что getUserInput () на время блокируется, а другой поток останавливает ваш поток худшим из возможных способов (он вызывает thread.stop ()). Ваш блок catch перехватит
ThreadDeath
ошибку. Это очень плохо. Поведение вашего кода после обнаружения этого исключения в значительной степени не определено.Аналогичная проблема возникает при перехвате исключения. Возможно,
getUserInput()
произошел сбой из-за InterruptException, исключения из-за отказа в разрешении при попытке записать результаты или всевозможных других сбоев. Вы понятия не имеете, что пошло не так, поскольку из-за этого вы также не знаете, как решить проблему.У вас есть три лучших варианта:
1 - Поймать именно те исключения, которые вы умеете обрабатывать:
2 - Повторите вызов любого исключения, с которым вы столкнулись и не знаете, как с ним справиться:
3 - Используйте блок finally, чтобы не забывать о повторном броске:
источник
throw new Exception("Some additional info, eg. userId " + userId, e);
. Это будет зарегистрировано в одном приятном исключении с 10 причинами.Также имейте в виду, что когда вы поймаете
Throwable
, вы также можете поймать,InterruptedException
что требует особого обращения. Дополнительные сведения см. В разделе Работа с InterruptedException .Если вы хотите поймать только непроверенные исключения, вы также можете рассмотреть этот шаблон
Таким образом, когда вы изменяете свой код и добавляете вызов метода, который может генерировать проверенное исключение, компилятор напомнит вам об этом, а затем вы можете решить, что делать в этом случае.
источник
прямо из javadoc класса Error (который рекомендует не ловить их):
источник
Это неплохая практика, если у вас абсолютно не может быть пузыря исключений из метода.
Это плохая практика, если вы действительно не можете справиться с исключением. Лучше добавить к сигнатуре метода «выбросы», чем просто перехватить и повторно выбросить или, что еще хуже, обернуть его в RuntimeException и повторно выбросить.
источник
Throwable
экземпляров - например, для пользовательского журнала исключений.Поймать Throwable иногда необходимо, если вы используете библиотеки, которые с энтузиазмом бросают ошибки, иначе ваша библиотека может убить ваше приложение.
Однако при таких обстоятельствах лучше всего указать только конкретные ошибки, выдаваемые библиотекой, а не все объекты Throwables.
источник
Throwable - это базовый класс для всех классов, которые могут быть выброшены (не только исключения). Вы мало что можете сделать, если поймаете OutOfMemoryError или KernelError (см. Когда поймать java.lang.Error? )
ловушки исключений должно быть достаточно.
источник
это зависит от вашей логики или, если быть более конкретным, от ваших опций / возможностей. Если есть какое-либо конкретное исключение, на которое вы можете отреагировать осмысленным образом, вы можете сначала его поймать и сделать это.
Если его нет, и вы уверены, что сделаете то же самое для всех исключений и ошибок (например, выйдите с сообщением об ошибке), то поймать бросаемый объект не проблема.
Обычно держится первый футляр, и бросок не поймаешь. Но есть еще масса случаев, когда ловля работает нормально.
источник
Хотя это описывается как очень плохая практика, иногда вы можете найти редкие случаи, когда это не только полезно, но и обязательно. Вот два примера.
В веб-приложении, где вы должны показать пользователю полную страницу с ошибкой. Этот код гарантирует, что это произойдет, поскольку он
try/catch
важен для всех ваших обработчиков запросов (сервлеты, действия struts или любой контроллер ...)}
В качестве другого примера представьте, что у вас есть класс обслуживания, который обслуживает бизнес по переводу средств. Этот метод возвращает,
TransferReceipt
если передача произведена илиNULL
нет.Теперь вы получаете информацию
List
о денежных переводах от пользователя, и вы должны использовать вышеуказанный сервис, чтобы сделать их все.Но что будет, если произойдет какое-то исключение? Вы не должны останавливаться, поскольку одна передача могла быть успешной, а другая - нет, вы должны продолжать проходить через всех пользователей
List
и показывать результат каждой передаче. Итак, вы получаете этот код.Вы можете просмотреть множество проектов с открытым исходным кодом, чтобы убедиться, что они
throwable
действительно кэшируются и обрабатываются. Например здесь является поискtomcat
,struts2
иprimefaces
:https://github.com/apache/tomcat/search?utf8=%E2%9C%93&q=catch%28Throwable https://github.com/apache/struts/search?utf8=%E2%9C%93&q=catch % 28Throwable https://github.com/primefaces/primefaces/search?utf8=%E2%9C%93&q=catch%28Throwable
источник
throwable
, вот о чем этот вопросВопрос немного расплывчатый; вы спрашиваете: «можно ли поймать
Throwable
» или «можно ли пойматьThrowable
и ничего не делать»? Многие здесь ответили на последнее, но это побочный вопрос; В 99% случаев вы не должны «потреблять» или отбрасывать исключение, независимо от того, ловите ли выThrowable
илиIOException
что-то еще.Если вы распространяете исключение, ответ (как и ответ на очень многие вопросы) - «это зависит от обстоятельств». Это зависит от того, что вы делаете, за исключением того, почему вы его ловите.
Хороший пример того, почему вы хотели бы поймать,
Throwable
- обеспечить некоторую очистку в случае какой-либо ошибки. Например, в JDBC, если во время транзакции возникает ошибка, вам нужно откатить транзакцию:Обратите внимание, что исключение не отбрасывается, а распространяется.
Но, как правило, ловить,
Throwable
потому что у вас нет причины и вы слишком ленивы, чтобы увидеть, какие именно исключения выбрасываются, - это плохая форма и плохая идея.источник
Вообще говоря, вы хотите избежать перехвата
Error
s, но я могу придумать (по крайней мере) два конкретных случая, когда это уместно:AssertionError
безвредные в остальном.источник
Если мы используем throwable , он также охватывает Error и все.
Пример.
}
Вывод:
источник
Throwable - это суперкласс всех ошибок и исключений. Если вы используете Throwable в предложении catch, он не только перехватит все исключения, но и все ошибки. JVM выдает ошибки, чтобы указать на серьезные проблемы, которые не предназначены для обработки приложением. Типичными примерами для этого являются OutOfMemoryError или StackOverflowError. Оба они вызваны ситуациями, которые находятся вне контроля приложения и не могут быть обработаны. Поэтому вам не следует ловить Throwables, если вы не уверены, что это будет только исключение, находящееся внутри Throwable.
источник
Хотя, как правило, ловить Throwable - это плохая практика (о чем свидетельствуют многочисленные ответы на этот вопрос), сценарии, в которых отлов
Throwable
полезен, довольно распространены. Позвольте мне объяснить один такой случай, который я использую на своей работе, на упрощенном примере.Рассмотрим метод, который выполняет сложение двух чисел, и после успешного добавления он отправляет электронное уведомление определенным людям. Предположим, что возвращенное число важно и используется вызывающим методом.
Код для отправки предупреждений по электронной почте считывает множество конфигураций системы, и, следовательно, в этом блоке кода может быть множество исключений. Но мы не хотим, чтобы какое-либо исключение, возникшее во время отправки предупреждения, распространялось на вызывающий метод, поскольку этот метод просто связан с суммой двух целочисленных значений, которые он предоставляет. Следовательно, код для отправки предупреждений по электронной почте помещается в
try-catch
блок, гдеThrowable
он перехватывается, а любые исключения просто регистрируются, позволяя продолжить работу остальной части потока.источник
Exception
любыми средствами, но не ловиThrowable
.