Pourquoi utiliser "On Error Goto 0"?

Pourquoi avez-vous songé à utiliser <!-- Dans une application VB6?

cette instruction éteint le handler d'erreur et signifierait que toute erreur planterait l'application. Pourquoi en serait-il toujours souhaitable?

26
demandé sur CJ7 2012-04-03 00:37:19

4 réponses

dans VB6, vous pouvez spécifier que vous voulez que les erreurs soient traitées par un code particulier plus tard dans la routine:

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

il se peut, cependant, que le code qui déclenche l'erreur soit localisé, et vous ne voulez pas ce même gestionnaire pour tout le reste du code dans la routine. Dans ce cas, vous utiliserez "On Error Goto 0" comme suit:

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

Maintenant vous avez effectivement scopé la manipulation d'erreur pour exécuter seulement si cette ligne particulière de code échouer.

en appelant "On Error Goto 0" Vous ne dites pas que vous voulez que l'application se bloque immédiatement. Vous dites simplement que vous voulez désinscrire tout gestionnaire d'erreurs que vous avez pu configurer plus tôt dans la routine; les erreurs seront passées dans la pile d'appels aux routines d'appel, comme normal.

46
répondu Matt Dillard 2012-04-02 21:26:33

Puisqu'il semble être maladroit de décrire en mots, voici quelques exemples montrant où vous pouvez utiliser On Error GoTo 0 pour la gestion localisée et structurée des erreurs.

le premier est un Property Get dans une classe ("MicroDOM") qui implémente un DOM Léger basé sur une hiérarchie de Collections subclassées. Dans ce cas, nous voulons essayer de faire référence à un enfant disparu par son nom plutôt que par un index pour créer un enfant vide (pas d'attrbutes ou d'enfants):

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

le second est le code inline qui supprime un fichier s'il est présent:

On Error Resume Next
Kill strFilePath
On Error GoTo 0

le troisième est le code inline qui ne prend une action que si un fichier est présent:

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

alors qu'il peut sembler maladroit pour le non initié (exécution On Error GoTo 0 en deux endroits), le résultat est moins maladroit et plus structuré que d'avoir des radeaux de On Error GoTo Label que passer en arrière pour traiter diverses exceptions.

Le bonus est que vous gagnez de la portabilité de VBScript ainsi, depuis On Error GoTo Label n'est pas valide construire là.

8
répondu Bob77 2012-04-03 13:01:56

il éteint seulement la manipulation d'erreur dans la procédure actuelle. S'il y a un gestionnaire d'erreurs dans la procédure d'appel, il attrapera toutes les exceptions qui n'ont pas été traitées. VB continue de monter, la pile d'appel jusqu'à ce qu'il trouve un gestionnaire d'erreur. S'il n'en trouve pas, alors il causera l'erreur d'exécution.

Donc pour un exemple - peut-être que vous avez une fonction wrapper qui appelle certains utilitaire tiers qui peut lever une exception. Au lieu de gérer les exceptions dans la fonction wrapper vous mettez un