【问题标题】:Try-Catch-End Try in VBScript doesn't seem to workTry-Catch-End Try 在 VBScript 中似乎不起作用
【发布时间】:2011-02-15 02:25:06
【问题描述】:

我正在尝试以下代码:

Try ' DOESN'T WORK
    Throw 2 ' How do I throw an exception?
Catch ex
    'What do I do here?
End Try

但我在 catch 子句中收到错误 Statement expected

有谁知道我如何在 VBScript 中使用 try/catch 捕获/抛出异常? (我不是在寻找On Error Do X 的解决方案。)

【问题讨论】:

  • 那你会非常失望的。在 .NET 之前的 VB 版本中没有 Try-Catch 支持,包括 VB 6、VBA 和 VBScript。 On Error Resume Next 还不错如果你知道如何正确使用它
  • 以下是一些正确使用它的提示! :-)

标签: vbscript try-catch


【解决方案1】:

处理错误

在 VBScript 中我们可以使用一种“旧式”的错误处理方式,它确实使用了On Error Resume Next。首先我们启用它(通常在文件的顶部;但您可以使用它代替下面的第一个 Err.Clear 以获得它们的组合效果),然后在运行我们可能产生错误的代码之前,清除所有已经发生的错误,运行可能产生错误的代码,然后显式检查错误:

On Error Resume Next
' ...
' Other Code Here (that may have raised an Error)
' ...
Err.Clear      ' Clear any possible Error that previous code raised
Set myObj = CreateObject("SomeKindOfClassThatDoesNotExist")
If Err.Number <> 0 Then
    WScript.Echo "Error: " & Err.Number
    WScript.Echo "Error (Hex): " & Hex(Err.Number)
    WScript.Echo "Source: " &  Err.Source
    WScript.Echo "Description: " &  Err.Description
    Err.Clear             ' Clear the Error
End If
On Error Goto 0           ' Don't resume on Error
WScript.Echo "This text will always print."

上面,如果发生错误,我们只是打印出错误。如果错误对脚本来说是致命的,您可以将第二个 Err.clear 替换为 WScript.Quit(Err.Number)

还要注意On Error Goto 0,它会在发生错误时关闭在下一条语句处恢复执行。

如果您想测试Set 成功时的行为,请继续注释该行,或创建一个将成功的对象,例如vbscript.regexp

On Error 指令仅影响当前运行的作用域(当前的SubFunction),不影响调用或被调用作用域。


引发错误

如果您想检查某种状态,然后引发错误以由调用您的函数的代码处理,您可以使用Err.RaiseErr.Raise 最多接受五个参数,NumberSourceDescriptionHelpFileHelpContext。使用帮助文件和上下文超出了本文的范围。 Number 是您选择的错误编号,Source 是引发错误的应用程序/类/对象/属性的名称,Description 是对所发生错误的简短描述。

If MyValue <> 42 Then
    Err.Raise(42, "HitchhikerMatrix", "There is no spoon!")
End If

然后您可以按照上面讨论的方式处理引发的错误。


更改日志

  • 编辑#1: 在可能导致错误的行之前添加了Err.Clear,以清除可能已被忽略的任何先前错误。
  • 编辑#2: 澄清。
  • 编辑#3: 在代码块中添加了 cmets。澄清在On Error Resume NextErr.Clear 之间预计会有更多代码。修复了一些语法以减少尴尬。添加了关于Err.Raise 的信息。格式化。
  • 【讨论】:

    • 我更喜欢“If Err”而不是“If Err.Number 0”,但这主要是一种风格偏好。
    • 我本来打算改变它,但是调用 Err.Clear 并在之后使用“if not null”样式检查对我来说有点奇怪。一切都取决于风格偏好。
    • 第一个Err.Clear 是多余的,因为On Error Resume Next 会为您重置Err 对象。也不要提及Err.Raise VBScript 错误处理库中非常有用的工具。
    • @Lankymart 谢谢。我已经澄清了为什么我有第一个Err.Clear。我添加了有关Err.Raise 的信息。
    • 有道理,感谢您的清晰说明。关于引发错误的主题,您可能会发现 this article 很有趣
    【解决方案2】:

    VBScript 没有 Try/Catch。 (VBScript language reference。如果有 Try,它将列在 Statements 部分。)

    On Error Resume Next 是 VBScript 中唯一的错误处理。对不起。如果你想尝试/捕捉,JScript 是一个选项。它在 VBScript 所在的任何地方都受支持,并且具有相同的功能。

    【讨论】:

    • 如果没有Try/Catch,那Try怎么不会出错?
    • 我想它也必须支持 Trraoysfoaiuerlkj,因为如果你将 Try 更改为它也不会出错。 ;) 我猜它认为 Try 可能是脚本后面出现的 Sub 的名称。
    • 没错,VBScript 将其视为不带参数的 Sub,因此如果不使用 Option Explicit 或使用 On Error Resume Next 不会出错。这就是为什么您应该定期使用 Option Explicit 并很少使用 On Error Resume Next 的原因。因为如果您打错字,您可以通过提及未声明的语句或无法识别的子/函数来轻松检测到它。
    • 哦,我从来不知道 Option Explicit 可以在 VBScript 中工作……我只在 VB 6 中使用过,谢谢! (我还认为 Try 是一个关键字,因为 Notepad++ 突出显示了 Try and Catch... :\ )
    • @Tmdean 我实际上用谷歌搜索了 Trraoysfoaiuerlkj。谢谢天才。
    【解决方案3】:

    通过 VBScript 中的解决方法尝试 Catch exists

    http://web.archive.org/web/20140221063207/http://my.opera.com/Lee_Harvey/blog/2007/04/21/try-catch-finally-in-vbscript-sure

    Class CFunc1
        Private Sub Class_Initialize
            WScript.Echo "Starting"
            Dim i : i = 65535 ^ 65535 
            MsgBox "Should not see this"
        End Sub
    
        Private Sub CatchErr
            If Err.Number = 0 Then Exit Sub
            Select Case Err.Number
                Case 6 WScript.Echo "Overflow handled!" 
                Case Else WScript.Echo "Unhandled error " & Err.Number & " occurred."
            End Select
            Err.Clear
        End Sub
    
        Private Sub Class_Terminate
            CatchErr
            WScript.Echo "Exiting" 
        End Sub 
    End Class
    
    Dim Func1 : Set Func1 = New CFunc1 : Set Func1 = Nothing
    

    【讨论】:

    • 虽然这有点酷,但从聪明的意义上说,“聪明”的代码很少可读或易于维护/使用。我对此做 -1 感到不舒服,但这对于生产目的来说确实是“糟糕的代码”。不过在学术上很酷。
    【解决方案4】:

    有时,尤其是在使用 VB 时,您可能会错过明显的解决方案。就像我过去 2 天所做的那样。

    需要将产生错误的代码移至单独的函数。在函数的开头写On Error Resume Next。这就是如何“吞下”错误,而不会吞下任何其他错误。将代码分成小的独立函数还可以提高可读性、重构和更容易添加一些新功能。

    【讨论】:

    • 或者您可以将On Error Goto 0 放在生成错误的代码之后,这样您就不会产生函数调用的开销(并且不需要不执行任何操作的小函数实际工作)。
    猜你喜欢
    • 1970-01-01
    • 2020-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多