2012-04-02 11 views
23

Dlaczego kiedykolwiek używałbyś "On Error Goto 0" w aplikacji VB6?Dlaczego miałbyś używać "On Error Goto 0"?

To polecenie wyłącza obsługę błędów i oznaczałoby, że jakikolwiek błąd spowodowałby awarię aplikacji. Dlaczego byłoby to zawsze pożądane?

+5

Cóż, jest to z pewnością sposób na wdrożenie [fail-fast] (https://pl.wikipedia.org/wiki/Fail-fast) –

+0

Nie mam zainstalowanego VB6, ale przypuszczalnie każde stwierdzenie Goto dla -odoodporna etykieta spowodowałaby awarię aplikacji. –

+0

To brzmi jak komentarz kogoś, kto albo rzuca w błąd Błąd wznowienia Dalej na czele każdej procedury, a następnie ma tajemnicze nieszczęścia, które nie mogą być zdiagnozowane, lub ktoś, kto wkłada On Error GoTo MyHandler i tam po prostu wyskakuje MsgBox z takim samym błędem i tak. – Bob77

Odpowiedz

41

w VB6, można określić, że ma błędy mają być obsługiwane przez konkretnego kodu później w rutynowych:

Sub Bar() 
    On Error Goto MyHandler 
    ... 
    ...some code that throws an error... 
    ... 
    Exit Sub 
MyHandler: 
    ...some error handler code (maybe pops up a dialog) 
End Sub 

może się zdarzyć jednak, że kod, który zgłasza błąd jest zlokalizowana, i nie chcesz tego samego programu obsługi dla całej reszty kodu w procedurze. W takim przypadku, można użyć „On Error Goto 0” w następujący sposób:

Sub Bar() 
    ... 
    On Error Goto MyHandler 
    ...some code that throws an error... 
    On Error Goto 0 
    ... 
    ... 
    Exit Sub 
MyHandler: 
    ...some error handler code (maybe pops up a dialog) 
End Sub 

Teraz skutecznie scoped błąd obsługi wykonać tylko wtedy, gdy szczególności linia kodu nie powiedzie się.

Wywołanie "Przy błędzie Goto 0" NIE oznacza, że ​​chcesz natychmiast zawiesić aplikację. Po prostu mówisz, że chcesz wyrejestrować wszystkie procedury obsługi błędów, które mogłeś skonfigurować wcześniej w procedurze; Błędy będą przekazywane do stosu wywołań do wywoływania procedur, jak normalnie.

+2

Przechodzisz również na obsługę błędów w górę stosu do procedur wywołujących –

+0

Co zrobić, jeśli obecna procedura jest już na dole stosu wywołań? Czy widzisz w tym jakiś sens? Ponieważ błąd w tym miejscu spowodowałby awarię aplikacji. – CJ7

+4

Craig, to nie różniłoby się od zwykłego nieuprowadzenia obsługi błędów w pierwszej kolejności. Domyślnie, bez żadnej obsługi błędów, aplikacja ulegnie awarii. Często nawet na najwyższym poziomie jest jasne, które linie kodu mają "aktywne" rozwiązywanie błędów, a następnie, aby je ponownie wyłączyć. Załóżmy, że chcemy logować się tylko wtedy, gdy jakiś kod się nie powiedzie. Powinniśmy wyrejestrować program obsługi błędów po tym. Obsługa błędów nie zawsze polega na zapobieganiu awarii; może służyć do logowania lub czyszczenia zasobów systemowych. Rozbijanie może być pożądanym (świadomym) zachowaniem. –

4

Wyłącza obsługę błędów tylko w procedurze CURRENT. Jeśli w procedurze wywołania występuje procedura obsługi błędów, przechwyci wszystkie wyjątki, które nie zostały obsłużone. VB kontynuuje przechodzenie do stosu wywołań aż do znalezienia procedury obsługi błędów. Jeśli go nie znajdzie, spowoduje błąd w czasie wykonywania.

Dla przykładu - może masz funkcję opakowania, która wywołuje narzędzie innej firmy, które może rzucić wyjątek. Zamiast obsługi wyjątków w funkcji opakowania umieściliśmy tam On Error Goto 0. Tak więc osoba wywołująca funkcję opakowania otrzyma wyjątek przekazany do niej i, miejmy nadzieję, poradzi sobie z nią we właściwy sposób.

8

Ponieważ wydaje się niezdarne do opisania w słowach, oto kilka przykładów pokazujących, gdzie można użyć On Error GoTo 0 do zlokalizowanej, strukturalnej obsługi błędów.

Pierwszy to Property Get w klasie ("MicroDOM"), który implementuje lekki DOM oparty na hierarchii podklasy kolekcji. W tym przypadku chcemy próbą odwołania się do zaginionego dziecka po imieniu zamiast indeksu Aby utworzyć pusty (nie attrbutes lub dzieci) dziecko:

Public Property Get Child(ByVal Key As Variant) As MicroDOM 
    If mChildren Is Nothing Then 
     Set mChildren = New Collection 
    End If 
    On Error Resume Next 
    Set Child = mChildren(Key) 
    If Err Then 
     On Error GoTo 0 
     If VarType(Key) = vbString Then 
      Key = Trim$(Key) 
      Set Child = New MicroDOM 
      Child.Key = Key 
      mChildren.Add Child, Key 
     Else 
      Err.Raise 9 'Subscript error as thrown by the Collection. 
     End If 
    End If 
End Property 

Drugi inline kod, który usuwa plik, jeśli jest obecny:

On Error Resume Next 
Kill strFilePath 
On Error GoTo 0 

trzeci jest inline kod, który wykonuje działania tylko wtedy, gdy plik dzieje się znajdować:

On Error Resume Next 
GetAttr strFilePath 
If Err Then 
    On Error GoTo 0 
    ProcessTheData strFilePath 
End If 
On Error GoTo 0 

Chociaż może się wydawać niewygodne dla niewtajemniczonych (wykonującemu On Error GoTo 0 w dwóch miejscach) wynik jest mniej niezgrabny i bardziej uporządkowany niż tratwy On Error GoTo Label, które przeskakują tam iz powrotem, aby przetworzyć różne wyjątki.

Dodatek jest taki, że zyskujesz także możliwość przenoszenia na VBScript, ponieważ On Error GoTo Label nie jest w ogóle prawidłową konstrukcją.