VBScript - Verwenden der Fehlerbehandlung

85

Ich möchte VBScript verwenden, um Fehler abzufangen und zu protokollieren (dh bei Fehler "etwas protokollieren") und dann die nächste Zeile des Skripts fortzusetzen.

Beispielsweise,

On Error Resume Next
'Führen Sie Schritt 1 aus
'Führen Sie Schritt 2 aus
'Führen Sie Schritt 3 aus

Wenn in Schritt 1 ein Fehler auftritt, möchte ich, dass dieser Fehler protokolliert wird (oder andere benutzerdefinierte Funktionen damit ausgeführt werden) und dann in Schritt 2 fortgesetzt wird. Ist dies möglich? und wie kann ich es implementieren?

EDIT: Kann ich so etwas machen?

Bei Fehler Setzen Sie myErrCatch fort
'Führen Sie Schritt 1 aus
'Führen Sie Schritt 2 aus
'Führen Sie Schritt 3 aus

myErrCatch:
'Protokollfehler
Weiter Weiter
apandit
quelle
1
Dylans Antwort ist ungefähr so ​​gut wie die von VB in der Fehlerbehandlungsabteilung. Deshalb habe ich immer Javascript verwendet, wenn ich damit durchkommen konnte.
wcm

Antworten:

160

VBScript hat keine Vorstellung davon, Ausnahmen auszulösen oder abzufangen, aber die Laufzeit stellt ein globales Err-Objekt bereit, das die Ergebnisse der zuletzt ausgeführten Operation enthält. Sie müssen nach jeder Operation explizit prüfen, ob die Err.Number-Eigenschaft ungleich Null ist.

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

Die Syntax "On Error Goto [label]" wird von Visual Basic und Visual Basic für Applikationen (VBA) unterstützt, VBScript unterstützt diese Sprachfunktion jedoch nicht, sodass Sie On Error Resume Next wie oben beschrieben verwenden müssen.

Dylan Beattie
quelle
3
Sie können WScript.Echo in der If-Anweisung ändern, um eine Funktion oder ein Sub aufzurufen, die wiederum die Anwendung
beenden
"enthält die Wiederverwendungen der zuletzt ausgeführten Operation". Ist das wahr? Es scheint, als würde der letzte Fehler angezeigt, was einen großen Unterschied darstellt.
Damien Golding
Trotz der Dokumentation von MS, die vorschlägt, dass err.clearnach jeder Überprüfung des Objekts verwendet werden muss, um zu verhindern, dass frühere Fehler die nächste Überprüfung auslösen (z. B. technet.microsoft.com/en-us/library/ee692852.aspx ), wird meiner Erfahrung errnach " von selbst "im Verlauf des Skripts. Ohne weitere Tests zu verwenden, schätze ich, dass Objekt-Clearings errals Nebenprodukt ihrer internen Operationen verwendet werden.
user66001
@ user66001 Einverstanden, aber noch sicherer explizit anzurufen Err.Clear.
Lankymart
12

Beachten Sie, dass dies On Error Resume Nextnicht global festgelegt ist. Sie können Ihren unsicheren Teil des Codes, z. B. in eine Funktion einfügen, die bei Auftreten eines Fehlers sofort unterbrochen wird, und diese Funktion von einem Sub mit einer vorhergehenden OERNAnweisung aufrufen .

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
Omegastripes
quelle
1
Nicht das klarste Beispiel, das ich je gesehen habe, aber ich verstehe das Konzept.
Lankymart
7
@Lankymart Würde es Ihnen etwas ausmachen, ein klareres Beispiel zu verknüpfen, das Sie damals gesehen haben, oder stattdessen vorzuschlagen, wie Omegastripes dieses Beispiel verbessern können?
Dominick
3
Für eine Sekunde hatte ich den Eindruck, dass ich ein neues Software-Engineering-Paradigma namens "Omegastripes" verpasst habe. Lol
TheBlastOne
4

Sie können Ihre Schritte Funktionsaufrufe in einer Fassadenfunktion neu gruppieren:

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

Lassen Sie dann Ihre Fehlerbehandlung in einer oberen Funktion sein, die die Fassade aufruft:

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

Nehmen wir nun an, es wird step3()ein Fehler ausgelöst. Da facade()keine Fehler behandeln (es gibt keine On error resume next in facade()), wird der Fehler wieder auf main()und step4()und step5()wird nicht ausgeführt.

Ihre Fehlerbehandlung wird jetzt in 1 Codeblock überarbeitet

Cid
quelle
1

Ich bin außergewöhnlich neu in VBScript, daher wird dies möglicherweise nicht als bewährte Methode angesehen, oder es gibt einen Grund, warum dies nicht so gemacht werden sollte, wie ich es noch nicht kenne, aber dies ist die Lösung, die ich zum Trimmen gefunden habe Reduzieren Sie die Menge an Fehlerprotokollierungscode in meinem Hauptcodeblock.

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
MistyDawn
quelle
1
Dies ist ASP Classic, nicht einfach altes VBScript
Jobbo