5

在我的机器上,下列代码片段中的每一个会抛出异常,而不是打印到标准输出“1”和“2” 为什么异常不被捕获?PowerShell - 为什么“除以零例外”不被捕获?

try { 
    [int]$a = 1/0 
} 
catch { 
    write 1 
} 
finally { 
    write 2 
} 

try { 
    [int]$a = 1/0 
} 
catch [System.Exception] { 
    write 1 
} 
finally { 
    write 2 
} 

回答

10

由于您正在使用常量,解释程序会尝试预计算结果,并失败,除以零错误。你的代码甚至没有被执行,所以没有什么可以陷阱。

您可以通过将您的代码更改为使用变量,强制执行它来验证这一点。

try { 
    $divisor = 0 
    [int]$a = 1/$divisor 
} 
catch { 
    write 1 
} 
finally { 
    write 2 
} 

的Windows PowerShell在行动(第257页)

这里的例子使用了1/$空。之所以做这个而不是 只是1/0,是因为PowerShell解释器做了一些叫做 的常量表达式折叠。

它查看仅包含常量值的表达式。当 看到一个,它在编译时评估该表达式,因此它不需要浪费时间在运行时重新执行一次。

这意味着不可能的表达式,例如被零除, 被捕获并视为解析错误。解析错误不能被捕获 ,并且当它们以交互方式输入时不会被记录,因此它们不是 就是一个很好的例子。 (如果一个脚本调用另一个脚本和 脚本有这些错误之一,调用脚本可以赶上它,但 脚本可以被解析不行。)

1

你可以试着投用那种线的例外:trap { "Your Exception" } 1/0
这将“0分”抛出异常。虽然我不明白为什么你的代码不会抛出异常。
PS:是不是应该是catch [System.SystemException]? :)

4

的RuntimeException在V2不开捕。它已在v3中修复。

划分为零属于此类别。

+0

+1 - 你有参考吗? –

+1

所以......我的不好。 :)它不是RuntimeException。我刚刚复制了FullyQualifiedErrorId,并且没有包含该场景的重要细节。 关于v3:我找不到任何参考(尚未)。 Doug Finke在他即将出版的书“PowerShell for Developers”中提到了这一计算方法,因此我尝试并意识到在v3中它实际上可以被捕获。对不起,由于使用错误的术语造成的任何混淆... :) – BartekB

+0

Thx为更新。如果你找到一个参考,我希望你仍然可以在这里发布。 –

相关问题