VBScript: utilizzo della gestione degli errori


86

Voglio usare VBScript per rilevare gli errori e registrarli (ad esempio in caso di errore "registra qualcosa") quindi riprendere la riga successiva dello script.

Per esempio,

In caso di errore, riprendi dopo
'Eseguire il passaggio 1
'Eseguire il passaggio 2
'Eseguire il passaggio 3

Quando si verifica un errore nel passaggio 1, voglio che registri quell'errore (o esegua altre funzioni personalizzate con esso), quindi riprendi dal passaggio 2. È possibile? e come posso implementarlo?

EDIT: posso fare qualcosa di simile?

In caso di errore, riprendi myErrCatch
'Eseguire il passaggio 1
'Eseguire il passaggio 2
'Esegui il passaggio 3

myErrCatch:
'errore di registro
Riprendi successivo

1
La risposta di Dylan è buona quasi quanto VB ottiene nel reparto di gestione degli errori. Questo è il motivo per cui ho sempre usato Javascript quando potevo farla franca.
wcm

Risposte:


163

VBScript non ha la nozione di lanciare o catturare eccezioni, ma il runtime fornisce un oggetto Err globale che contiene i risultati dell'ultima operazione eseguita. È necessario verificare esplicitamente se la proprietà Err.Number è diversa da zero dopo ogni operazione.

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 sintassi "On Error Goto [label]" è supportata da Visual Basic e Visual Basic for Applications (VBA), ma VBScript non supporta questa funzionalità del linguaggio, quindi è necessario utilizzare On Error Resume Next come descritto sopra.


3
È possibile modificare WScript.Echo all'interno dell'istruzione If per chiamare una funzione o un sub, che a sua volta potrebbe uscire dall'applicazione, registrare l'errore, ecc.
StormPooper

"contiene i risultati dell'ultima operazione eseguita". È vero? Sembra che riceva l'ultimo errore che è una grande differenza.
Damien Golding

Nonostante la documentazione di MS suggerisca che err.cleardeve essere utilizzato dopo ogni controllo dell'oggetto, per evitare che errori precedenti facciano scattare il controllo successivo (ad esempio, technet.microsoft.com/en-us/library/ee692852.aspx ), nella mia esperienza errè cancellato " da solo "man mano che la sceneggiatura procede. Senza ulteriori test, la mia ipotesi sta utilizzando oggetti clear errcome sottoprodotto delle loro operazioni interne.
user66001

@ user66001 Concordato ma ancora più sicuro da chiamare esplicitamente Err.Clear.
user692942

12

Nota che On Error Resume Nextnon è impostato globalmente. Puoi mettere la tua parte di codice non sicura, ad esempio, in una funzione, che verrà interrotta immediatamente se si verifica un errore, e chiamare questa funzione dal sub contenente l' OERNistruzione precedente .

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
Non è l'esempio più chiaro che abbia mai visto, ma ho capito il concetto.
user692942

7
@Lankymart ti dispiacerebbe collegare un esempio più chiaro che hai visto allora, o invece suggerire come gli omegastripes possono migliorare questo esempio?
Dominick

3
Per un secondo, ho avuto l'impressione di essermi perso un nuovo paradigma di ingegneria del software chiamato "omegastripes" lol
TheBlastOne

4

È possibile raggruppare le chiamate alle funzioni dei passaggi in una funzione facciata:

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

Quindi, lascia che la tua gestione degli errori sia in una funzione superiore che chiama la facciata:

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

Supponiamo ora che step3()generi un errore. Dal momento che facade()non gestisce gli errori (non v'è alcuna On error resume next in facade()), l'errore verrà restituito main()e step4()e step5()non verrà eseguito.

La tua gestione degli errori è ora riformulata in 1 blocco di codice


1

Sono eccezionalmente nuovo in VBScript, quindi questa potrebbe non essere considerata la migliore pratica o potrebbe esserci un motivo per cui non dovrebbe essere fatto in questo modo non ne sono ancora a conoscenza, ma questa è la soluzione che ho trovato per tagliare ridurre la quantità di codice di registrazione degli errori nel mio blocco di codice principale.

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
Questo è ASP Classic, non un semplice vecchio VBScript
Jobbo
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.