VBScript ——使用错误处理

我想使用 VBScript 捕捉错误并记录它们(即在错误“ log something”上) ,然后恢复脚本的下一行。

比如说,

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

当步骤1中出现错误时,我希望它记录该错误(或对其执行其他自定义函数) ,然后在步骤2中恢复。这可能吗?我如何实现它?

编辑: 我能做这样的事情吗?

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


myErrCatch:
'log error
Resume Next
341994 次浏览

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.

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

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

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

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