95

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
1
  • 1
    Dylan's response is about as good as VB gets in the Error handling department. This is why I always used Javascript when I could get away with it.
    – wcm
    Commented Oct 1, 2008 at 14:23

6 Answers 6

173

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.

5
  • 3
    You could change WScript.Echo within the If statement to call a Function or Sub, which could in turn exit the application, log the error, etc.
    – StormFoo
    Commented Mar 21, 2013 at 15:08
  • "contains the reuslts of the last operation performed". Is that true? Seems like it gets the last error which is a big difference. Commented Jun 13, 2014 at 0:47
  • Despite MS's documentation suggesting that err.clear needs to be used after each check of the object, to prevent previous errors tripping the next check (e.g., technet.microsoft.com/en-us/library/ee692852.aspx), in my experience err is cleared "by itself" as the script progresses. Without testing further, my guess is utilising objects clears err as a by product of their internal operations.
    – user66001
    Commented Dec 2, 2014 at 17:45
  • @user66001 Agreed but still safer to explicitly call Err.Clear.
    – user692942
    Commented Oct 21, 2015 at 11:16
  • You absolutely can throw exceptions in VBScript with the Err.Raise() method.
    – user692942
    Commented Jun 16, 2022 at 6:27
13

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
5
  • 1
    Not the clearest example I've ever seen but I get the concept.
    – user692942
    Commented Oct 21, 2015 at 11:17
  • 7
    @Lankymart would you mind linking a clearer example that you've seen then, or instead suggest how omegastripes can improve this example?
    – Dominick
    Commented Feb 23, 2016 at 15:18
  • 3
    For a second, I got the impression I missed a new software engineering paradigm called "omegastripes" lol Commented Jul 17, 2016 at 9:30
  • Wouldn't ErrStep have to be ByRef?
    – mbomb007
    Commented May 11, 2021 at 14:38
  • @mbomb007 arguments are ByRef by default. Commented May 12, 2021 at 14:00
10

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

1

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
1
  • 2
    This is ASP Classic, not plain old VBScript
    – Jobbo
    Commented Feb 28, 2019 at 17:10
0

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
0

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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.