Возврат исключения из улова исключения - PullRequest
2 голосов
/ 14 февраля 2011

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

Вроде так:

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 голосов
/ 14 февраля 2011

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

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

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

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

Throw New Exception("My new message", ex)
1 голос
/ 14 февраля 2011

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

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

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

0 голосов
/ 14 февраля 2011

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...