VBScript - Utilisation de la gestion des erreurs


84

Je veux utiliser VBScript pour attraper les erreurs et les enregistrer (c'est-à-dire en cas d'erreur "enregistrer quelque chose") puis reprendre la ligne suivante du script.

Par exemple,

En cas d'erreur Reprendre suivant
'Faites l'étape 1
'Faites l'étape 2
'Faites l'étape 3

Lorsqu'une erreur se produit à l'étape 1, je souhaite qu'il enregistre cette erreur (ou exécute d'autres fonctions personnalisées avec elle) puis reprend à l'étape 2. Est-ce possible? et comment puis-je le mettre en œuvre?

EDIT: Puis-je faire quelque chose comme ça?

En cas d'erreur, reprendre myErrCatch
'Faites l'étape 1
'Faites l'étape 2
'Faites l'étape 3

myErrCatch:
'erreur de journal
Reprendre suivant

1
La réponse de Dylan est à peu près aussi bonne que VB obtient dans le département de gestion des erreurs. C'est pourquoi j'ai toujours utilisé Javascript quand je pouvais m'en tirer.
wcm

Réponses:


161

VBScript n'a aucune notion de lever ou d'intercepter des exceptions, mais le runtime fournit un objet Err global qui contient les résultats de la dernière opération effectuée. Vous devez vérifier explicitement si la propriété Err.Number est différente de zéro après chaque opération.

On Error Resume Next

DoStep1

If Err.Number <> 0 Then
  WScript.Echo "Error in DoStep1: " & Err.Description
  Err.Clear
End If

DoStep2

If Err.Number <> 0 Then
  WScript.Echo "Error in DoStop2:" & Err.Description
  Err.Clear
End If

'If you no longer want to continue following an error after that block's completed,
'call this.
On Error Goto 0

La syntaxe «On Error Goto [label]» est prise en charge par Visual Basic et Visual Basic pour Applications (VBA), mais VBScript ne prend pas en charge cette fonctionnalité de langage, vous devez donc utiliser On Error Resume Next comme décrit ci-dessus.


3
Vous pouvez modifier WScript.Echo dans l'instruction If pour appeler une fonction ou un sous-marin, ce qui pourrait à son tour quitter l'application, enregistrer l'erreur, etc.
StormPooper

"contient les réutilisations de la dernière opération effectuée". Est-ce vrai? On dirait qu'il obtient la dernière erreur, ce qui est une grande différence.
Damien Golding

Malgré la documentation de MS suggérant que cela err.cleardoit être utilisé après chaque vérification de l'objet, pour éviter que les erreurs précédentes ne déclenchent la vérification suivante (par exemple, technet.microsoft.com/en-us/library/ee692852.aspx ), d'après mon expérience, errest effacée " par lui-même »au fur et à mesure que le script progresse. Sans tester davantage, je suppose que j'utilise des objets effacés errcomme sous-produit de leurs opérations internes.
user66001

@ user66001 Accepté mais toujours plus sûr d'appeler explicitement Err.Clear.
Lankymart

12

Notez que ce On Error Resume Nextn'est pas défini globalement. Vous pouvez mettre votre partie de code non sécurisée, par exemple dans une fonction, qui s'interrompra immédiatement si une erreur se produit, et appeler cette fonction à partir d'un sous contenant l' OERNinstruction précédente .

ErrCatch()

Sub ErrCatch()
    Dim Res, CurrentStep

    On Error Resume Next

    Res = UnSafeCode(20, CurrentStep)
    MsgBox "ErrStep " & CurrentStep & vbCrLf & Err.Description

End Sub

Function UnSafeCode(Arg, ErrStep)

    ErrStep = 1
    UnSafeCode = 1 / (Arg - 10)

    ErrStep = 2
    UnSafeCode = 1 / (Arg - 20)

    ErrStep = 3
    UnSafeCode = 1 / (Arg - 30)

    ErrStep = 0
End Function

1
Ce n'est pas l'exemple le plus clair que j'ai jamais vu mais je comprends le concept.
Lankymart

7
@Lankymart vous dérangerait-il de lier un exemple plus clair que vous avez vu alors, ou suggérez-vous plutôt comment omegastripes peut améliorer cet exemple?
Dominick

3
Pendant une seconde, j'ai eu l'impression d'avoir raté un nouveau paradigme de génie logiciel appelé "omegastripes" lol
TheBlastOne

4

Vous pouvez regrouper vos appels de fonctions d'étapes dans une fonction de façade:

sub facade()
    call step1()
    call step2()
    call step3()
    call step4()
    call step5()
end sub

Ensuite, laissez votre gestion des erreurs être dans une fonction supérieure qui appelle la façade:

sub main()
    On error resume next

    call facade()

    If Err.Number <> 0 Then
        ' MsgBox or whatever. You may want to display or log your error there
        msgbox Err.Description
        Err.Clear
    End If

    On Error Goto 0
end sub

Maintenant, supposons que step3()génère une erreur. Étant donné que facade()ne gère pas d' erreurs (il n'y a pas On error resume next dans facade()), l'erreur sera retourné main()et step4()et step5()ne sera pas exécuté.

Votre gestion des erreurs est désormais refactorisée en 1 bloc de code


1

Je suis exceptionnellement nouveau dans VBScript, donc cela peut ne pas être considéré comme une meilleure pratique ou il peut y avoir une raison pour laquelle cela ne devrait pas être fait de cette façon dont je ne suis pas encore au courant, mais c'est la solution que j'ai trouvée pour couper réduire la quantité de code de journalisation des erreurs dans mon bloc de code principal.

Dim oConn, connStr
Set oConn = Server.CreateObject("ADODB.Connection")
connStr = "Provider=SQLOLEDB;Server=XX;UID=XX;PWD=XX;Databse=XX"

ON ERROR RESUME NEXT

oConn.Open connStr
If err.Number <> 0 Then : showError() : End If


Sub ShowError()

    'You could write the error details to the console...
    errDetail = "<script>" & _
    "console.log('Description: " & err.Description & "');" & _
    "console.log('Error number: " & err.Number & "');" & _
    "console.log('Error source: " & err.Source & "');" & _
    "</script>"

    Response.Write(errDetail)       

    '...you could display the error info directly in the page...
    Response.Write("Error Description: " & err.Description)
    Response.Write("Error Source: " & err.Source)
    Response.Write("Error Number: " & err.Number)

    '...or you could execute additional code when an error is thrown...
    'Insert error handling code here

    err.clear
End Sub

1
Ceci est ASP Classic, pas tout à fait vieux VBScript
Jobbo
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.