Powershell $ Error对象不会立即填充PSM1模块内部

Eth*_*own 8 powershell exception-handling

我遇到了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)"  
  }
}
Run Code Online (Sandbox Code Playgroud)

如果你打电话给Bar,输出就像你期望的那样

Caught an error - current error count 1
Cleaning up - current error count 1
Run Code Online (Sandbox Code Playgroud)

我遇到问题的代码几乎完全相同,只是它从模块加载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
Run Code Online (Sandbox Code Playgroud)

然后我执行以下操作

Import-Module .\Foo.psm1
$Error.Clear()
"Current error count $($Error.Count)"
Foo
"Current error count $($Error.Count)"
Run Code Online (Sandbox Code Playgroud)

我结束了

Current error count 0
Caught an error - current error count 0
Cleaning up - current error count 0
Current error count 1
Run Code Online (Sandbox Code Playgroud)

请注意,Foo不再看到对$ Error所做的任何更改.因此代码的模块化正在改变错误传播行为.任何人都可以在这背后推理吗?

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

小智 11

正如Ethan所提到的,你需要查看$ global:error来查看所有错误.模块总是拥有它们自己的$ error变量,但它(大部分)都没有使用过.

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

微软公司的Bruce Payette


x0n*_*x0n 9

之前我没有注意到,但是也许$ error集合的范围与任何其他变量一样.尝试比较测试脚本中关键点的以下两个显式范围变量的值:

"Errors - Global: {0}; Module: {1}" -f $global:error.count, $script:error.count
Run Code Online (Sandbox Code Playgroud)

让我知道你是怎么办的.

  • 确实可以通过$ global访问错误:错误.我在操作中略读了9.4.5的PS ...我理解了范围解析规则.我仍然不明白为什么甚至会有一个模块级$ Error对象,当在模块内投掷时不会修改它.特有.恕我直言,违反了最少惊喜的原则,因为您可以在模块中使用$ Error.Add()来修改本地作用域集合,但任何类型的throw都会修改全局作用域集合. (2认同)