VBScript: uso del manejo de errores

84

Quiero usar VBScript para detectar errores y registrarlos (es decir, en el error "registrar algo") y luego reanudar la siguiente línea del script.

Por ejemplo,

En caso de error, reanudar siguiente
'Haz el paso 1
'Haz el paso 2
'Haz el paso 3

Cuando ocurre un error en el paso 1, quiero que registre ese error (o realice otras funciones personalizadas con él) y luego reanude en el paso 2. ¿Es esto posible? y como puedo implementarlo?

EDITAR: ¿Puedo hacer algo como esto?

En caso de error, reanudar myErrCatch
'Haz el paso 1
'Haz el paso 2
'Haz el paso 3

myErrCatch:
'error de registro
Reanudar Siguiente
apandit
fuente
1
La respuesta de Dylan es tan buena como VB en el departamento de manejo de errores. Es por eso que siempre usé Javascript cuando podía salirme con la mía.
wcm

Respuestas:

161

VBScript no tiene la noción de lanzar o capturar excepciones, pero el tiempo de ejecución proporciona un objeto Err global que contiene los resultados de la última operación realizada. Debe verificar explícitamente si la propiedad Err.Number es distinta de cero después de cada operación.

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 sintaxis "On Error Goto [etiqueta]" es compatible con Visual Basic y Visual Basic para Aplicaciones (VBA), pero VBScript no es compatible con esta función de lenguaje, por lo que debe utilizar On Error Resume Next como se describe anteriormente.

Dylan Beattie
fuente
3
Puede cambiar WScript.Echo dentro de la instrucción If para llamar a una función o sub, que a su vez podría salir de la aplicación, registrar el error, etc.
StormPooper
"contiene los reuslts de la última operación realizada". ¿Es eso cierto? Parece que recibe el último error, lo cual es una gran diferencia.
Damien Golding
A pesar de que la documentación de MS sugiere que err.cleardebe usarse después de cada verificación del objeto, para evitar errores anteriores que activen la siguiente verificación (p. Ej., Technet.microsoft.com/en-us/library/ee692852.aspx ), en mi experiencia errestá claro " por sí mismo "a medida que avanza el guión. Sin probar más, mi conjetura es utilizar objetos claros errcomo un subproducto de sus operaciones internas.
user66001
@ user66001 De acuerdo, pero aún es más seguro llamar explícitamente Err.Clear.
Lankymart
12

Tenga en cuenta que On Error Resume Nextno está configurado globalmente. Puede poner su parte insegura del código, por ejemplo, en una función, que se interrumpirá inmediatamente si se produce un error, y llamar a esta función desde el sub que contiene la OERNdeclaración 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
omegastripes
fuente
1
No es el ejemplo más claro que he visto, pero entiendo el concepto.
Lankymart
7
@Lankymart, ¿le importaría vincular un ejemplo más claro que haya visto entonces, o en su lugar sugerir cómo las rayas omegas pueden mejorar este ejemplo?
Dominick
3
Por un segundo, tuve la impresión de que me perdí un nuevo paradigma de ingeniería de software llamado "omegastripes" lol
TheBlastOne
4

Puede reagrupar sus llamadas a funciones de pasos en una función de fachada:

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

Luego, deje que su manejo de errores esté en una función superior que llame a la fachada:

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

Ahora, supongamos que step3()genera un error. Dado que facade()no maneja errores (no hay ninguna On error resume next en facade()), el error será devuelto a main()y step4()y step5()no se ejecutará.

Su manejo de errores ahora se refactoriza en 1 bloque de código

Cid
fuente
1

Soy excepcionalmente nuevo en VBScript, por lo que es posible que esto no se considere la mejor práctica o puede haber una razón por la que no debería hacerse de esa manera que aún no conozco, pero esta es la solución que se me ocurrió para recortar reducir la cantidad de código de registro de errores en mi bloque de código 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
MistyDawn
fuente
1
Esto es ASP Classic, no VBScript simple y antiguo
Jobbo