about_Trap

簡単な説明

終了エラーを処理するキーワードについて説明します。

長い説明

終了エラーは、ステートメントの実行を停止します。 PowerShell で何らかの方法で終了エラーが処理されない場合、PowerShell は現在のパイプラインで関数またはスクリプトの実行も停止します。 C# などの他の言語では、終了エラーは例外と呼ばれます。

このキーワードは trap 、終了エラーが発生したときに実行するステートメントのリストを指定します。 trap ステートメントは、次の方法で終了エラーを処理できます。

  • ステートメント ブロックを処理し、そのステートメントブロックを trap 含むスクリプトまたは関数の実行を続行した後、エラーを表示します trap。 これは既定の動作です。

    注意

    ステートメントやforeachループなどのif下位スクリプト ブロックで終了エラーが発生すると、ブロック内のtrapステートメントが実行され、下位スクリプト ブロックの外部の次のステートメントで実行が続行されます。

  • ステートメント内の using break を含むスクリプトまたは関数のエラーと中止の実行をtraptrap表示します。

  • エラーを無音にしますが、ステートメントで使用continueして、そのスクリプトまたは関数を含むtrapスクリプトまたは関数の実行をtrap続行します。

ステートメントの一覧には、複数の trap 条件または関数呼び出しを含めることができます。 A trap は、ログを書き込んだり、条件をテストしたり、別のプログラムを実行したりできます。

構文

trap ステートメントの構文は次のとおりです。

trap [[<error type>]] {<statement list>}

ステートメント trap には、終了エラーが発生したときに実行するステートメントの一覧が含まれています。 ステートメントは trap 、キーワード ( trap 必要に応じて型式) と、エラーがトラップされたときに実行するステートメントの一覧を含むステートメント ブロックで構成されます。 型式は、キャッチするエラーの種類を trap 調整します。

スクリプトまたはコマンドには、複数の trap ステートメントを含めることができます。 trap ステートメントは、スクリプトまたはコマンド内の任意の場所に表示できます。

終了するすべてのエラーをトラップする

スクリプトまたはコマンドで別の方法で処理されない終了エラーが発生した場合、PowerShell はエラーを trap 処理するステートメントを確認します。 ステートメントが存在する trap 場合、PowerShell はステートメント内のスクリプトまたはコマンドを trap 引き続き実行します。

次の例は、非常に単純なステートメントです trap

trap {"Error found."}

このステートメントは trap 、終了エラーをトラップします。

次の例では、ランタイム エラーの原因となるナンセンス文字列が関数に含まれています。

function TrapTest {
    trap {"Error found."}
    nonsenseString
}

TrapTest

この関数を実行すると、次の結果が返されます。

Error found.
nonsenseString : The term 'nonsenseString' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was
included, verify that the path is correct and try again.
At line:3 char:5
+     nonsenseString
+     ~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (nonsenseString:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

次の例には、自動変数を trap 使用してエラーを表示するステートメントが $_ 含まれています。

function TrapTest {
    trap {"Error found: $_"}
    nonsenseString
}

TrapTest

このバージョンの関数を実行すると、次の結果が返されます。

Error found: The term 'nonsenseString' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
nonsenseString : The term 'nonsenseString' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was
included, verify that the path is correct and try again.
At line:3 char:5
+     nonsenseString
+     ~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (nonsenseString:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

重要

trap ステートメントは、特定のスクリプト ブロック内の任意の場所で定義できますが、そのスクリプト ブロック内のすべてのステートメントに常に適用されます。 実行時には、 trap ブロック内のステートメントは、他のステートメントが実行される前に定義されます。 JavaScript では、これは ホイストと呼ばれます。 つまり、定義されている trap 時点を超えて実行が進んでいなくても、そのブロック内のすべてのステートメントにステートメントが適用されます。 たとえば、スクリプトの最後に a を trap 定義し、最初のステートメントでエラーをスローすると、そのエラーが引き続きトリガー trapされます。

特定のエラーのトラップ

スクリプトまたはコマンドには、複数の trap ステートメントを含めることができます。 A trap は、特定のエラーを処理するために定義できます。

次の例は、特定の trap エラー CommandNotFoundException をトラップするステートメントです。

trap [System.Management.Automation.CommandNotFoundException]
    {"Command error trapped"}

関数またはスクリプトが既知のコマンドと一致しない文字列を検出すると、この trap ステートメントは "Command error trapped" 文字列を表示します。 ステートメント リストを trap 実行した後、PowerShell はエラー オブジェクトをエラー ストリームに書き込み、スクリプトを続行します。

PowerShell では、.NET 例外の種類が使用されます。 次の例では、 System.Exception エラーの種類を指定します。

trap [System.Exception] {"An error trapped"}

CommandNotFoundException エラーの種類は、System.Exception 型から継承されます。 このステートメントは、不明なコマンドによって作成されたエラーをトラップします。 また、他のエラーの種類もトラップします。

スクリプトには複数の trap ステートメントを含めることができます。 各エラーの種類は、1 つの trap ステートメントによってのみトラップできます。 終了エラーが発生すると、PowerShell trap は、現在のスクリプト実行ブロックから開始して、最も具体的な一致を検索します。

次のスクリプトの例には、エラーが含まれています。 スクリプトには、終了エラーをトラップする一般的trapなステートメントと、CommandNotFoundException 型を指定する特定trapのステートメントが含まれています。

trap {"Other terminating error trapped" }
trap [System.Management.Automation.CommandNotFoundException] {
  "Command error trapped"
}
nonsenseString

このスクリプトを実行すると、次の結果が生成されます。

Command error trapped
nonsenseString : The term 'nonsenseString' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was
included, verify that the path is correct and try again.
At C:\Temp\traptest.ps1:5 char:1
+ nonsenseString
+ ~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (nonsenseString:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

PowerShell はコマンドレットまたはその他の項目として "nonsenseString" を認識しないため、 CommandNotFoundException エラーを返します。 この終了エラーは、特定 trap のステートメントによってトラップされます。

次のスクリプト例には、エラーが異なる同じ trap ステートメントが含まれています。

trap {"Other terminating error trapped" }
trap [System.Management.Automation.CommandNotFoundException]
    {"Command error trapped"}
1/$null

このスクリプトを実行すると、次の結果が生成されます。

Attempted to divide by zero.
At C:\temp\traptest.ps1:4 char:1
+ 1/$null
+ ~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], RuntimeException
    + FullyQualifiedErrorId : RuntimeException

0 で除算しようとしても 、CommandNotFoundException エラーは発生しません。 代わりに、そのエラーは他 trap のステートメントによってトラップされ、終了エラーがトラップされます。

スクリプト ブロック内のエラーのトラップ

既定では、終了エラーがスローされると、実行は trap ステートメントに転送されます。 ブロックが trap 実行されると、エラーの場所の後の次のステートメント ブロックに制御が戻ります。

たとえば、ステートメントで foreach 終了エラーが発生すると、ステートメントが実行され、 trap ブロック内ではなく、ブロックの後の次の foreach ステートメントで実行が foreach 続行されます。

trap { 'An error occurred!'}
foreach ($x in 3..0) {
   1/$x
   'after division'
}
'after loop'
0.333333333333333
after division
0.5
after division
1
after division
An error occurred!
Attempted to divide by zero.
At line:3 char:4
+    1/$x
+    ~~~~
    + CategoryInfo          : NotSpecified: (:) [], RuntimeException
    + FullyQualifiedErrorId : RuntimeException

after loop

上記の出力では、ループが最後のイテレーションまで続くことがわかります。 スクリプトが 1 を 0 で除算しようとすると、終了エラーがスローされます。 スクリプトブロックの foreach 残りの部分はスキップされ、 try ステートメントが実行され、スクリプトブロックの後にスクリプトが foreach 続行されます。

エラーとスコープのトラップ

ステートメントと同じスクリプト ブロック trap で終了エラーが発生した場合は、PowerShell によって定義されたステートメントの一覧が trap実行されます。 エラーの後、ステートメントで実行が続行されます。 ステートメントが trap エラーとは異なるスクリプト ブロック内にある場合は、ステートメントと同じスクリプト ブロック内にある次のステートメントで実行が trap 続行されます。

たとえば、関数でエラーが発生し、ステートメントが trap 関数内にある場合、スクリプトは次のステートメントで続行されます。 次のスクリプトには、エラーとステートメントが trap 含まれています。

function function1 {
    trap { "An error: " }
    NonsenseString
    "function1 was completed"
}

function1

このスクリプトを実行すると、次の結果が生成されます。

An error:
NonsenseString : The term 'NonsenseString' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was
included, verify that the path is correct and try again.
At line:3 char:5
+     NonsenseString
+     ~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (NonsenseString:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

function1 was completed

関数内のステートメントによって trap エラーがトラップされます。 メッセージを表示すると、PowerShell は関数の実行を再開します。 完了した点に Function1 注意してください。

これは、同じエラーとステートメントを持つ次の例と trap 比較します。 この例では、ステートメントは trap 関数の外部で発生します。

function function2 {
    NonsenseString
    "function2 was completed"
}

trap { "An error: " }

function2

関数を Function2 実行すると、次の結果が生成されます。

An error:
NonsenseString : The term 'NonsenseString' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was
included, verify that the path is correct and try again.
At C:\temp\traptest.ps1:2 char:5
+     NonsenseString
+     ~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (NonsenseString:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

この例では、"function2 が完了しました" コマンドは実行されませんでした。 どちらの例でも、終了エラーは関数内で発生します。 ただし、この例では、 trap ステートメントは関数の外部にあります。 PowerShell は、ステートメントの実行後に関数に trap 戻りません。

注意事項

同じエラー条件に対して複数のトラップが定義されている場合、最初 trap に定義された構文 (スクリプト ブロック内で最も高い) が使用されます。

次の例では、"whoops 1" の場合のみ trap 実行されます。

Remove-Item -ErrorAction Stop ThisFileDoesNotExist
trap { "whoops 1"; continue }
trap { "whoops 2"; continue }

重要

Trap ステートメントのスコープは、コンパイル先です。 関数またはドットソーススクリプト内にステートメントがある trap 場合、関数またはドットソーススクリプトが終了すると、内部のすべての trap ステートメントが削除されます。

break キーワードと continue キーワードの使用

ステートメント内の and continue キーワードをbreaktrap使用して、終了エラーの後もスクリプトまたはコマンドが引き続き実行されるかどうかを判断できます。

ステートメントリストにtrapステートメントをbreak含める場合、PowerShell は関数またはスクリプトを停止します。 次のサンプル関数では、ステートメント内のキーワードをbreaktrap使用します。

function break_example {
    trap {
        "Error trapped"
        break
    }
    1/$null
    "Function completed."
}

break_example
Error trapped
Attempted to divide by zero.
At line:6 char:5
+     1/$null
+     ~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : RuntimeException

ステートメントに trap キーワードが break 含まれているため、関数は引き続き実行されず、"Function completed" 行は実行されません。

ステートメントにキーワードをcontinue含めると、エラーの原因となったステートメントの後に PowerShell が再開されます。エラーが発生しないbreak場合とcontinue同様trapです。 ただし、キーワードを continue 使用しても、PowerShell はエラー ストリームにエラーを書き込むことはありません。

次のサンプル関数では、ステートメント内のキーワードをcontinuetrap使用します。

function continue_example {
    trap {
        "Error trapped"
        continue
    }
    1/$null
    "Function completed."
}

continue_example
Error trapped
Function completed.

エラーがトラップされた後に関数が再開され、"Function completed" ステートメントが実行されます。 エラー ストリームにエラーが書き込まれなくなりました。

メモ

trap ステートメントは、スクリプト ブロック内のすべての終了エラーが確実に処理されるようにする方法を提供します。 より詳細なエラー処理を行うには、ステートメントを使用 try/catch してトラップを定義するブロックを使用 catch します。 ステートメントは catch 、関連付けられた try ステートメント内のコードにのみ適用されます。 詳細については、「about_Try_Catch_Finally」 参照してください。

こちらもご覧ください