鉴于vbscript
没有与On Error Goto MyLabel
一样的vba
语法,我正在考虑使用以下方法来处理错误:
On Error Resume Next
'Do some stuff
If Err.Number <> 0 Then
Err.Clear
'Handle the error
End If
'Do some more stuff
If Err.Number <> 0 Then
Err.Clear
'Handle the error
End If
'...
我的问题是:这种技术对速度的影响是什么?
此外,我想知道是否有更好的方法可以将一些错误处理构建到vbscript
答案 0 :(得分:2)
本地错误处理的习惯用语:
Dim gaErr ' global error array
...
Sub SomeSub()
...
OERN
risky op
gaErr = Array(Err.Number, Err.Description, ...)
OEG0
If gaErr(0) Then
handle error
...
End Sub
如果您的规范需要进行全局错误处理:
Dim gaErr
OERN
ret = main()
gaErr = Array(...)
OEG0
If gaErr(0) Then
some fatal/not locally handled error occured somewhere in your script
handle it gracefully
Else
If ret is bad Then
deal with this
Else
ask for more money
End If
End If
WScript.Quit good/bad
Function main()
main = ...
End Function
更新评论:
为什么全球OERN邪恶?考虑:
OERN
(1) Process/change important data
(2) Delete original data - if (1) failed you just destroyed the base of your business
OERN
(1) Process/change important data
(2) If Err.Nunber Then Backup(database, destinatiom)
(3) Continue although the Backup didn't take place, because at least three error were hidden
BTW:您添加的Err.Clear位置错误 - 您在错误信息之前错过可以处理错误。
更新评论II:
考虑这个演示脚本:
' dgeh.vbs - demo global error handling
Option Explicit
' globals
Dim gWAN : Set gWAN = WScript.Arguments.Named
Dim gaErr
Dim iRet
' top-level/global OERN starts here (errors before will abort mercylessly)
On Error Resume Next
iRet = main() ' not more than two statements!
gaErr = Array(Err.Number, Err.Description, Err.Source)
On Error GoTo 0
If gaErr(0) Then
WScript.Echo "Fatal Error:", Join(gaErr, " * ")
iRet = 1 ' or choose a better number
Else
If iRet Then
WScript.Echo "need one of /good, /bad, or /fatal, Mr. User!"
Else
WScript.Echo "all's well"
End If
End If
WScript.Quit iRet
Function main()
main = 2
If gWAN.Count = 1 And (gWAN.Exists("good") Or gWAN.Exists("bad") Or gWAN.Exists("fatal")) Then
readTheDocs
main = 0
End If
End Function
Sub readTheDocs()
WScript.Echo "read Microsoft's Docs"
If gWAN.Exists("fatal") Then
caTastrophy
Else
trySomethingRisky
End If
End Sub
Sub trySomethingRisky()
Dim n
If gWAN.Exists("bad") Then n = 1 / 0
WScript.Echo "but be skeptical of the text and your interpretation"
End Sub
Sub caTastrophy()
On Error Resume Next ' simulating the evil global OERN and not checking *each* statement
WScript.Echo "saving the world"
saveTheWorld
WScript.Echo "deleting the now obsolete original"
On Error GoTo 0
End Sub
的输出
cscript dgeh.vbs /fatal
read Microsoft's Docs
saving the world
deleting the now obsolete original
all's well
echo %ERRORLEVEL%
0
由于没有Sub saveTheWorld,您只是进行了错误处理,VBScript以及其他所有内容都已过时。你甚至不能再承诺永远不再使用邪恶的全球OERN了,因为你 - 以及那些习惯性地使用它的脚本家伙(从而证明他们的笑话,而不是他们的代码)已经消失了。我们希望调用进程不会将ERRORLEVEL值作为进一步删除的许可证。
的输出
cscript dgeh.vbs
need one of /good, /bad, or /fatal, Mr. User!
echo %ERRORLEVEL%
2
cscript dgeh.vbs /nix
need one of /good, /bad, or /fatal, Mr. User!
cscript dgeh.vbs /fatal /bad
need one of /good, /bad, or /fatal, Mr. User!
展示“先跳过你”的策略。
良好案例的输出:
cscript dgeh.vbs /good
read Microsoft's Docs
but be skeptical of the text and your interpretation
all's well
echo %ERRORLEVEL%
0
显示两条消息(正确地说是这样)。
现在完全不同了:
cscript dgeh.vbs /bad
read Microsoft's Docs
Fatal Error: 11 * Division by zero * Microsoft VBScript runtime error
echo %ERRORLEVEL%
1
请标记缺少第二条消息。除以零将导致在活动OERN范围中执行下一行(保存在gaErr中)并且不继续盲目地/盲目地继续。然后检查危险操作(执行main()及其所有子操作)(通过gaErr代理)。这符合规则“在OERN范围内不超过两行(冒险操作和保存错误信息)”。
为这种全局错误处理付出的代价:您丢失了行号信息 - 优雅地处理错误变得更加困难。
但是由于你的脚本中只有一个OERN(从现在开始你的程序中不会有Sub caTastrophy()),你可以在开发和调试过程中对它进行注释。
OERN的输出评论说:cscript dgeh.vbs /bad
read Microsoft's Docs
E:\trials\SoTrials\answers\21901890\vbs\dgeh.vbs(46, 30) Microsoft VBScript runtime error: Division by zero
答案 1 :(得分:0)
当我在Vbscript中使用错误处理时,我发现它没有性能问题。但是在我的程序中,它通常会做一些非常简单的事情,例如将“失败”语句输出到日志文件然后wscript.quit
,所以我从未发现它会降低系统性能。在您提供的示例中,通常会在检查错误的最后On Error Goto 0
之后添加End If
。这可能导致错误无法清除,因此当您下次执行错误检查时,它仍然错误地存储了旧的错误值。