В чем смысл этого высказывания Catch?

Я видел это в устаревшем коде. Что, если таковые имеются, является целью одного броска внутри Catch?

       Try
           'Some Oracle access statement
       Catch err As OracleClient.OracleException
            Throw
       Finally
          'Do something
       End Try

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

Ответ 1

Похоже, он используется, чтобы выпустить ошибку. В то время как обычно можно было бы добавить больше в инструкцию catch, чем просто бросить (например, вести журнал, оповещения и т.д.), В этом случае он позволяет использовать оператор finally для выполнения некоторой очистки, а затем пропускать ошибку до следующего уровня. Без try/catch, как бы этот код очистки был написан в этой области? Как уже упоминалось ранее, синтаксис throw (без ex) сохраняет трассировку стека.

Ответ 2

Я часто использовал этот шаблон при отладке; Я установлю точку останова на оператор throw, чтобы проверить err. Не уверен, есть ли еще одна веская причина сделать это, хотя.

Ответ 3

Многие думают, что это не-op, но это не так. Если у вас есть эта программа:

Module Module1
    Function Filter() As Boolean
        Console.WriteLine("1")
        Return True
    End Function

    Sub Thrower()
        Try
            Throw New Exception("x")
        Finally
            Console.WriteLine("3")
        End Try
    End Sub

    Sub NoCatch()
        Try
            Thrower()
        Finally
            Console.WriteLine("2")
        End Try
    End Sub

    Sub WithCatch()
        Try
            Thrower()
        Catch ex As Exception
            Throw
        Finally
            Console.WriteLine("2")
        End Try
    End Sub

    Sub Caller(ByVal method As Action)
        Try
            method()
        Catch ex As Exception When Filter()
        End Try
    End Sub

    Sub Main()
        Console.WriteLine("No Catch")
        Caller(AddressOf NoCatch)
        Console.WriteLine("With Catch")
        Caller(AddressOf WithCatch)
    End Sub
End Module

Выходной сигнал

No Catch
1
3
2
With Catch
3
1
2

Изменить: один сценарий, когда это действительно имеет значение: Функции Thrower и NoCatch находятся в одной и той же сборке, которая застревает. Метод Caller не является надежным и злонамеренным. Теперь представьте, что метод Thrower использует WindowsIdentity для олицетворения другого пользователя, которого недопустимая сборка не позволяет делать. Затем он полагается на используемый блок (= try/finally), чтобы исключить пользователя, но он выдает исключение. Это означает, что вредоносная сборка выполняется как олицетворенный пользователь во время выполнения метода фильтра. Возможно, это будет работать и при утверждении разрешений, но я не уверен.

Ответ 4

Это будет повторная ошибка. Это позволит вам выполнять работу в блоке "Окончание", в то же время повторяя ошибку вызывающему абоненту

ИЗМЕНИТЬ

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

Ответ 5

Это ничего не делает. Бросьте, как есть правильно.

Вы можете удалить уловку, но вы хотите оставить попытку, если в конце есть больше комментариев.

Ответ 6

Он ловит ошибку, а затем снова бросает ее. Я не вижу смысла, потому что вы можете попробовать Try... Наконец без предложения Catch...

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

Ответ 7

Основная причина использования throw без параметра заключается в том, что он сохранит исходный стек.

Кроме того, вместо того, чтобы помещать точку останова в оператор throw, вы могли бы изменить свои VS-настройки, чтобы разбить исключения oracle, что намного проще, чем добавить точки останова по всему месту