programowanieProgramista VB.NET, Programista Backend

Jak realizuje się obsługa i ponowne rzucanie (rethrow) wyjątków w Visual Basic? Jakie są różnice między operatorem Throw a Throw ex, i czym grozi niewłaściwe ponowne rzucenie wyjątku?

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź

W Visual Basic do obsługi wyjątków używa się bloku Try...Catch...Finally. Aby ponownie rzucić wyjątek po jego przechwyceniu — tzn. przekazać go dalej w stosie wywołań — stosuje się operator Throw lub Throw ex.

Różnice:

  • Throw (bez parametru) ponownie rzuca bieżący wyjątek, zachowując oryginalny stos wywołań (Call Stack).
  • Throw ex rzuca obiekt wyjątku, ale zeruje stos wywołań — informacje o miejscu rzeczywistego wystąpienia problemu.

Zaleca się używać Throw bez parametrów do prawidłowego ponownego rzucania wyjątku, jeśli nie został on zmodyfikowany.

Przykład prawidłowego ponownego rzucenia:

Try DangerousOperation() Catch ex As Exception ' Logowanie... Throw ' zachowuje stos wywołań End Try

Nieprawidłowy sposób:

Try DangerousOperation() Catch ex As Exception Throw ex ' Stos wywołań zerowany, diagnostyka utrudniona End Try

Pytanie z pułapką

Co się stanie ze stosem wywołań, jeśli użyjesz Throw ex zamiast Throw?

Przy użyciu Throw bez parametru zachowuje się oryginalny stos wywołań — ten, w którym wystąpił wyjątek. Jeśli użyjesz Throw ex, to stos zaczyna się od bieżącej linii, a oryginalne miejsce wystąpienia ginie. Utrudnia to debugowanie, ponieważ nie zobaczysz, w której części kodu wystąpił problem.

Przykłady rzeczywistych błędów spowodowanych nieznajomością szczegółów tematu


Historia

W dużym projekcie bankowym programiści używali Throw ex do rzucania błędów logicznych. Podczas analizy logów okazało się, że nie można było ustalić miejsca wystąpienia wyjątków, ponieważ brakowało im poprawnego śledzenia.


Historia

W warstwie dostępu do danych używano Throw do ponownego rzucania SqlException, ale w niektórych przypadkach narzędzie do autofomatowania kodu automatycznie zastąpiło to Throw ex. To zepsuło system automatycznego pobierania danych z logów i wydłużyło czas reakcji na incydenty.


Historia

Próba modyfikacji obiektu Exception i ponownego rzucenia go przez Throw bez parametru spowodowała, że zmiany nie odzwierciedliły się w logach — pomogło tylko jawne stworzenie nowego obiektu wyjątku z zachowaniem oryginalnego jako InnerException.