Повторное выбрасывание исключения из улова исключений

Обновить

November 2018

Просмотры

2.5k раз

2

Это хорошая идея, чтобы поймать исключение, а затем бросить еще одно исключение?

Вот так:

Try
    ' Do operation xxx
Catch ex As Exception
    ' Operation xxx failed, need to execute cleanup
    ' But now I've caught this exception outside of my main control logic, 
    ' so I would like to re-throw it
    Throw New ApplicationException("XXX failed")
End Try

Причина этого в том, что в то время как я ловлю мое исключение на более высоком логическом уровне (чтобы убедиться, что я могу войти это правильно), что мне нужно сделать какие-то действия в случае, за исключением, что я могу сделать только в моем классе / функции ,

Вы можете думать о каких-либо причины / сценариях, почему это плохая идея?

3 ответы

10

Да, это плохая идея.

Прежде всего, не перехватывать исключения для того, чтобы выполнить очистку. Используйте Наконец блок для того, как он будет выполнен или не произошло исключение. Вам также не нужно, чтобы бросить новое исключение только сказать «XXX Failed». Трассировка стека показывает, что.

Во- вторых, не следует использовать ApplicationException. Microsoft используется рекомендовать определенные пользователем исключения происходят из ApplicationException, но это оказалось плохой идеей. Они рекомендуют мы просто использовать Exception.

Наконец, когда вы собираетесь бросить новое исключение из-за старую, не забудьте включить старое исключение:

Throw New Exception("My new message", ex)
1

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

Во- вторых, если вы хотите , чтобы бросить новое исключение , то либо просто выбросить исключение или создать свой собственный тип исключения на основе Exception. Я бы рекомендовал делать это , если вы поймать исключение низкого уровня , как I / O или SQL, и хочу повторно выдать что - то конкретное для операции , которая проводится. В этом случае вы можете гнездиться пойманным исключение как InnerException. Ищите конструктор перегружать , чтобы сделать это легко.

В-третьих, если вы хотите просто повторно выдать Я считаю, что вы можете просто написать «бросок», который неявно текущее исключение, что был пойман. По крайней мере, как вы делаете это в C #, который позволяет исключение с его весь стек трассировки и другие данные продолжают кипящий стек нетронутыми.

0

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

Я хотел бы также добавить , что 99% время , вы должны поймать конкретные исключения вместо общего Exceptionтипа. Если вы ловите все исключения, вы, скорее всего , скрывать неудачи вы не готовы справиться. Лучше пусть ваш сбой программы и сказать вам , что пошло не так , что оставить интересно , почему ваша программа не работает достаточно хорошо.

Связанные вопросы