apandit
apandit

Reputation: 3344

VBScript -- Using error handling

I want to use VBScript to catch errors and log them (ie on error "log something") then resume the next line of the script.

For example,

On Error Resume Next
'Do Step 1
'Do Step 2
'Do Step 3

When an error occurs on step 1, I want it to log that error (or perform other custom functions with it) then resume at step 2. Is this possible? and how can I implement it?

EDIT: Can I do something like this?

On Error Resume myErrCatch
'Do step 1
'Do step 2
'Do step 3

myErrCatch:
'log error
Resume Next

Upvotes: 95

Views: 368435

Answers (6)

david
david

Reputation: 2638

WSH files, .wsh, are XML files that can contain both jscript and vbscript, and allow you to run the vbscript from jscript, and the jscript from vbscript.

And the jscript engine includes an exception handler.

You could, of course, write your entire script in jscript. Or you could just write a jscript handler that logs exceptions, and use it in a .wsh file to call your vbscript.

Upvotes: 0

PravyNandas
PravyNandas

Reputation: 677

What @cid provided is a great answer. I took the liberty to extend it to next level by adding custom throw handler (like in javascript). Hope someone finds its useful.

option Explicit

Dim ErrorCodes
Set ErrorCodes = CreateObject("Scripting.Dictionary")
ErrorCodes.Add "100", "a should not be 1"
ErrorCodes.Add "110", "a should not be 2 either."
ErrorCodes.Add "120", "a should not be anything at all."

Sub throw(iNum)
    Err.Clear

    Dim key
    key = CStr(iNum)
    If ErrorCodes.Exists(key) Then
        Err.Description = ErrorCodes(key)
    Else
        Err.Description = "Error description missing."
    End If
    Err.Source = "Dummy stage"
    
    Err.Raise iNum 'raise a user-defined error
End Sub


Sub facade(a)
    if a=1 then
        throw 100
    end if

    if a = 2 then
        throw 110
    end if

    throw 120
End Sub

Sub Main
    on error resume next

        facade(3)

        if err.number <> 0 then
            Wscript.Echo Err.Number, Err.Description
        end if
    on error goto 0
End Sub

Main

Upvotes: 0

Cid
Cid

Reputation: 15257

You can regroup your steps functions calls in a facade function :

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

Then, let your error handling be in an upper function that calls the facade :

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

Now, let's suppose step3() raises an error. Since facade() doesn't handle errors (there is no On error resume next in facade()), the error will be returned to main() and step4() and step5() won't be executed.

Your error handling is now refactored in 1 code block

Upvotes: 10

MistyDawn
MistyDawn

Reputation: 903

I'm exceptionally new to VBScript, so this may not be considered best practice or there may be a reason it shouldn't be done this that way I'm not yet aware of, but this is the solution I came up with to trim down the amount of error logging code in my main code block.

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

Upvotes: 1

Dylan Beattie
Dylan Beattie

Reputation: 54160

VBScript has no notion of throwing or catching exceptions, but the runtime provides a global Err object that contains the results of the last operation performed. You have to explicitly check whether the Err.Number property is non-zero after each operation.

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

The "On Error Goto [label]" syntax is supported by Visual Basic and Visual Basic for Applications (VBA), but VBScript doesn't support this language feature so you have to use On Error Resume Next as described above.

Upvotes: 172

omegastripes
omegastripes

Reputation: 12612

Note that On Error Resume Next is not set globally. You can put your unsafe part of code eg into a function, which will interrupted immediately if error occurs, and call this function from sub containing precedent OERN statement.

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

Upvotes: 13

Related Questions