Powershell $Error 对象未立即填充到 PSM1 模块内

2024-02-22

我在使用 Powershell 时遇到了一个特殊问题。我在 catch 块中捕获异常,但未填充全局 $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 。不确定这是否是一个错误,或者只是我不理解的东西(必须检查我的 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 所做的任何更改。因此,代码的模块化正在改变错误传播行为。谁能解释一下这背后的原因吗?

我应该注意,我可以通过自动变量 $_ 获取特定的捕获异常,但我希望在调用堆栈中的此时获取整个集合。


正如 Ethan 提到的,您需要查看 $global:error 才能看到所有错误。模块总是有它们自己的 $error 变量,但它(大部分)没有被使用。

背景:曾经考虑过将模块代码中发生的错误隔离到模块范围,但最终决定将所有错误添加到全局错误集合中,因为它本质上是错误日志(如内存中事件日志)。不幸的是模块作用域 $error 在发布之前未被删除,因此您需要使用全局作用域限定符来访问“真实”$error 变量。

布鲁斯·帕耶特,微软公司

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Powershell $Error 对象未立即填充到 PSM1 模块内 的相关文章

随机推荐