Powershell的尝试捕捉
我试图赶上异常调用运行这样的其他功能的功能:Powershell的尝试捕捉
$ErrorActionPreference = "Stop"
function f {
$a = 1
$b = $a/0
}
function Main($f) {
try {
$f
} catch [System.Exception] {
"Caught exception"
}
}
Main(f)
的问题是,该异常没有被捕获像这样的PowerShell显示消息:
Attempted to divide by zero.
In C:\test.ps1:4 car:5
+ $b = $a/0
+ ~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : RuntimeException
为什么异常没有被捕获,即使$ErrorActionPreference = "Stop"
是对代码的顶部?
那么,你没有调用你的Main
函数,你调用f
函数,并将其输出作为Main
的输入,然后调用Main函数。使用Set-PSDebug并查看。
Set-PSDebug -Trace 2
现在测试:
Main(f)
DEBUG: ! CALL function '<ScriptBlock>'
DEBUG: ! SET $ErrorActionPreference = 'Stop'.
DEBUG: 15+ >>>> Main(f)
DEBUG: 2+ function f >>>> {
DEBUG: ! CALL function 'f'
DEBUG: 3+ >>>> 1/0
这枚返回1
function f {
1/1
}
function Main($f) {
try {
$f
} catch [System.Exception] {
"Caught exception"
}
}
Main(f)
这捕获预期:
function f {
1/1
}
function Main($f) {
try {
$f/0
} catch [System.Exception] {
"Caught exception"
}
}
Main(f)
编辑:为了澄清错误的第二答案,这与机智无关^ h预编译,它很容易与下面的代码可验证:
function f {
$a = 0
1/$a
}
function Main($input) {
try {
$input
} catch [System.Exception] {
"Caught exception"
}
}
Main(f)
感谢所有。我明白我的错误。 – guidros
@guidros好,如果其中一个答案帮助你将它标记为答案,谢谢! – 4c74356b41
问题是真的在这条线Main(f)
。所做的就是调用函数f
并尝试将结果传递给函数Main
。当然,在它可以得到结果之前,有一个异常,并且管道永远不会进入Main。你试图传递函数本身而不是结果。 PowerShell没有很好的方法直接做到这一点。这是一种脚本语言,不是一种功能语言。但是,您可以将参数声明为Main作为ScriptBlock并调用它。一个ScriptBlock就像一个函数对象。使用它将产生相同的效果。然而,获取函数的ScriptBlock有点麻烦。这应该是预期,是更标准的工作作风:
$ErrorActionPreference = "Stop"
function f {
$a = 1
$b = $a/0
}
function Main {
param([ScriptBlock]$f)
try {
& $f
} catch [System.Exception] {
"Caught exception"
}
}
Main -f { f }
所以不是我们传递的是只包含对f和调用该包装的调用一个新的脚本块。
请注意,我已经替换了C风格的函数调用语法。以我的经验来看,这种风格比在PowerShell中的价值更麻烦。坚持PowerShell风格,事情往往更清晰。
如果你真的想要得到的相关函数的脚本,你需要做的是这样的:
Main -f (get-command f).ScriptBlock
没有高阶函数在你的榜样 –