about_Trap
簡単な説明
終了エラーを処理するキーワードについて説明します。
長い説明
終了エラーは、ステートメントの実行を停止します。 PowerShell で何らかの方法で終了エラーが処理されない場合、PowerShell は現在のパイプラインで関数またはスクリプトの実行も停止します。 C# などの他の言語では、終了エラーは例外と呼ばれます。
このキーワードは trap
、終了エラーが発生したときに実行するステートメントのリストを指定します。 trap
ステートメントは、次の方法で終了エラーを処理できます。
ステートメント ブロックを処理し、そのステートメントブロックを
trap
含むスクリプトまたは関数の実行を続行した後、エラーを表示しますtrap
。 これは既定の動作です。注意
ステートメントや
foreach
ループなどのif
下位スクリプト ブロックで終了エラーが発生すると、ブロック内のtrap
ステートメントが実行され、下位スクリプト ブロックの外部の次のステートメントで実行が続行されます。ステートメント内の using
break
を含むスクリプトまたは関数のエラーと中止の実行をtrap
trap
表示します。エラーを無音にしますが、ステートメントで使用
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
キーワードをbreak
trap
使用して、終了エラーの後もスクリプトまたはコマンドが引き続き実行されるかどうかを判断できます。
ステートメントリストにtrap
ステートメントをbreak
含める場合、PowerShell は関数またはスクリプトを停止します。 次のサンプル関数では、ステートメント内のキーワードをbreak
trap
使用します。
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 はエラー ストリームにエラーを書き込むことはありません。
次のサンプル関数では、ステートメント内のキーワードをcontinue
trap
使用します。
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」 を参照してください。