9

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

$Error に加えられた変更が Foo に表示されなくなったことに注意してください。そのため、コードのモジュール化により、エラーの伝播動作が変化しています。この背後にある理由を理解できる人はいますか?

自動変数 $_ を介してキャッチされた特定の例外を取得できることに注意してください。ただし、コール スタックのこの時点でコレクション全体を取得しようとしています。

4

2 に答える 2

13

Ethan が述べたように、すべてのエラーを確認するには $global:error を確認する必要があります。モジュールには常に独自の $error 変数がありますが、(ほとんど) 使用されていません。

背景: ある時点で、モジュール コードで発生したエラーをモジュール スコープに分離することを検討しましたが、最終的にはすべてのエラーをグローバル エラー コレクションに追加することにしました。グローバル エラー コレクションは本質的にエラーのログ (メモリ内イベント ログなど) であるためです。残念ながら$error スコープのモジュールはリリース前に削除されなかったため、「実際の」 $error 変数にアクセスするには、グローバル スコープ修飾子を使用する必要があります。

マイクロソフト コーポレーション、ブルース ペイエット

于 2012-07-12T17:48:46.473 に答える
10

以前は気づいていませんでしたが、おそらく $error コレクションは、他の変数と同様にモジュールにスコープが設定されています。テスト スクリプトの重要なポイントで、次の 2 つの明示的に範囲指定された変数の値を比較してみてください。

"Errors - Global: {0}; Module: {1}" -f $global:error.count, $script:error.count

乗り方を教えてください。

于 2012-07-12T01:20:43.077 に答える