我遇到了Powershell的一个特殊问题。我在catch块中捕获了一个Exception,但是没有填充全局$ Error对象。
一个简单的例子,其表现如预期的那样:
function Bar
{
Foo
}
function Foo
{
try
{
$Error.Clear()
throw "Error!"
}
catch
{
"Caught an error - current error count $($Error.Count)"
}
finally
{
"Cleaning up - current error count $($Error.Count)"
}
}
如果您致电Bar
,则输出正如您所期望的那样Caught an error - current error count 1
Cleaning up - current error count 1
我遇到问题的代码几乎完全相同,只是它从模块加载Foo。不确定这是一个bug,还是我不理解的东西(必须检查我的Powershell in Action书!)
如果我将Foo保存到模块 - Foo.psm1
function Foo
{
try
{
$Error.Clear()
throw "Error!"
}
catch
{
"Caught an error - current error count $($Error.Count)"
}
finally
{
"Cleaning up - current error count $($Error.Count)"
}
}
Export-ModuleMember -Function Foo
然后我执行以下
Import-Module .\Foo.psm1
$Error.Clear()
"Current error count $($Error.Count)"
Foo
"Current error count $($Error.Count)"
我最终得到了
Current error count 0
Caught an error - current error count 0
Cleaning up - current error count 0
Current error count 1
请注意,Foo不再看到对$ Error所做的任何更改。因此代码的模块化正在改变错误传播行为。任何人都可以为这背后的推理而感到高兴吗?
我应该注意,我可以通过自动变量$ _来获取特定捕获的异常,但我希望在调用堆栈中此时保持整个集合。
答案 0 :(得分:10)
正如Ethan所提到的,你需要查看$ global:error来查看所有错误。模块总是有自己的$ error变量,但(大部分)没有使用它。
背景:有一次,我们考虑将模块代码中发生的错误隔离到模块范围,但最终决定将所有错误添加到全局错误集合中,因为它本质上是一个错误日志(如内存中的事件日志) 。)不幸的是,在发布之前没有删除模块作用域$ error,所以你需要使用全局作用域限定符来访问“真正的”$ error变量。
微软公司的Bruce Payette
答案 1 :(得分:8)
之前我没有注意到,但也许$ error集合的范围与任何其他变量一样。尝试比较测试脚本中关键点的以下两个显式范围变量的值:
"Errors - Global: {0}; Module: {1}" -f $global:error.count, $script:error.count
让我知道你是怎么过的。