about_Trap
簡単な説明
終了エラーを処理するキーワードについて説明します。
詳細な説明
終了エラーは、ステートメントの実行を停止します。 PowerShell で何らかの方法で終了エラーが処理されない場合、PowerShell は現在のパイプラインで関数またはスクリプトの実行も停止します。 C# などの他の言語では、終了エラーは例外と呼ばれます。
trap
キーワードは、終了エラーが発生したときに実行するステートメントの一覧を指定します。 trap
ステートメントは、次の方法で終了エラーを処理できます。
trap
ステートメント ブロックを処理し、trap
を含むスクリプトまたは関数の実行を継続した後、エラーを表示します。 これが既定の動作となります。Note
if
ステートメントやforeach
ループなどの下位スクリプト ブロックで終了エラーが発生すると、trap
ブロック内のステートメントが実行され、下位スクリプト ブロックの外部にある次のステートメントで実行が続行されます。trap
ステートメントでbreak
を使用して、trap
を含むスクリプトまたは関数のエラーと中止の実行を表示します。エラーを無音にしますが、
trap
ステートメントでcontinue
を使用して、trap
を含むスクリプトまたは関数の実行を続行します。
trap
のステートメント リストには、複数の条件または関数呼び出しを含めることができます。 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 では、これは hoisting と呼ばれます。 つまり、 trap
ステートメントは、定義されている時点を超えて実行が進んでいなくても、そのブロック内のすべてのステートメントに適用されます。 たとえば、スクリプトの最後に trap
を定義し、最初のステートメントでエラーをスローすると、 trap
引き続きトリガーされます。
特定のエラーのトラップ
スクリプトまたはコマンドには、複数の trap
ステートメントを含めることができます。 特定のエラーを処理するために、 trap
を定義できます。
次の例は、CommandNotFoundException特定のエラーをトラップするtrap
ステートメントです。
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 型から継承されます。 このステートメントは、不明なコマンドによって発生したエラーをトラップします。 また、他のエラーの種類もトラップします。
エラー オブジェクトを調べることで、エラーの例外の種類を見つけることができます。 次の例は、セッションの最後のエラーの例外の完全な名前を取得する方法を示しています。
nonsenseString
$Error[0].Exception.GetType().FullName
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:1 char:1
+ nonsenseString
+ ~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (nonsenseString:String) []
, CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
System.Management.Automation.CommandNotFoundException
スクリプトには複数の trap
ステートメントを含めることができます。 エラーの種類ごとにトラップできる trap
ステートメントは 1 つだけです。 終了エラーが発生すると、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 line: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
このスクリプトを実行すると、次の結果が生成されます。
Other terminating error trapped
Attempted to divide by zero.
At line:5 char:1
+ 1/$null}
+ ~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
0 で除算しても、 CommandNotFoundException エラーは発生しません。 もう 1 つの trap
ステートメントは、終了エラーをトラップし、ゼロ除算エラーをトラップします。
スクリプト ブロック内のエラーのトラップ
既定では、終了エラーがスローされると、実行はトラップ ステートメントに転送されます。 trap
ブロックが実行されると、エラーの場所の後の次のステートメント ブロックに制御が戻ります。
たとえば、foreach
ステートメントで終了エラーが発生すると、trap
ステートメントが実行され、foreach
ブロック内ではなく、foreach
ブロックの後の次のステートメントで実行が続行されます。
trap { 'An error occurred!'}
foreach ($x in 3..-1) {
"1/$x = "
"`t$(1/$x)"
}
'after loop'
1/3 =
0.333333333333333
1/2 =
0.5
1/1 =
1
1/0 =
An error occurred!
Attempted to divide by zero.
At line:3 char:4
+ 1/$x
+ ~~~~
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
after loop
出力では、ループが最後のイテレーションまで続くことがわかります。 スクリプトが 1 を 0 で除算しようとすると、PowerShell は終了エラーをスローします。 スクリプトは、 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 は関数の実行を再開します。 trap
ステートメントの後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 line:2 char:5
+ NonsenseString
+ ~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (NonsenseString:String) []
, CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
この例では、 function2 was completed
コマンドは実行されませんでした。 どちらの例でも、終了エラーは関数内で発生します。 ただし、この例では、 trap
ステートメントは関数の外部にあります。 trap
ステートメントの実行後、PowerShell は関数に戻りません。
注意事項
同じエラー条件に対して複数のトラップが定義されている場合、最初の trap
(スクリプト ブロック内で最も高い) 構文的に定義されます。
次の例では、whoops 1
を含むtrap
のみが実行されます。
Remove-Item -ErrorAction Stop ThisFileDoesNotExist
trap { 'whoops 1'; continue }
trap { 'whoops 2'; continue }
重要
trap
ステートメントのスコープは、コンパイル先です。 関数またはドットソーススクリプト内に trap
ステートメントがある場合、関数またはドットソーススクリプトが終了すると、内部のすべての trap
ステートメントが削除されます。
break キーワードと continue キーワードの使用
trap
ステートメントでbreak
キーワードとcontinue
キーワードを使用して、終了エラーの後もスクリプトまたはコマンドが引き続き実行されるかどうかを判断できます。
trap
ステートメント リストに break
ステートメントを含める場合、PowerShell は関数またはスクリプトを停止します。 次のサンプル関数では、trap
ステートメントで break
キーワードを使用します。
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: (:) [], ParentContainsErrorR
ecordException
+ FullyQualifiedErrorId : RuntimeException
trap
ステートメントには break
キーワードが含まれているため、関数の実行は続行されず、Function completed
行は実行されません。
trap
ステートメントに continue
キーワードを含めると、break
やcontinue
が発生しない場合と同様に、エラーの原因となったステートメントの後に PowerShell が再開されます。 ただし、 continue
キーワードでは、PowerShell はエラー ストリームにエラーを書き込むことはありません。
次のサンプル関数では、trap
ステートメントで continue
キーワードを使用します。
function ContinueExample {
trap {
'Error trapped'
continue
}
foreach ($x in 3..-1) {
"1/$x = "
"`t$(1/$x)"
}
'End of function'
}
ContinueExample
1/3 =
0.333333333333333
1/2 =
0.5
1/1 =
1
1/0 =
Error trapped
End of function
エラーがトラップされた後に関数が再開され、 End of function
ステートメントが実行されます。 エラー ストリームにエラーは書き込まれなくなります。
メモ
trap
ステートメントを使用すると、スクリプト ブロック内のすべての終了エラーが確実に処理されます。 より詳細なエラー処理を行うには、catch
ステートメントを使用してトラップを定義するtry
/catch
ブロックを使用します。 catch
ステートメントは、関連付けられている try
ステートメント内のコードにのみ適用されます。 詳細については、「 about_Try_Catch_Finally」を参照してください。
関連項目
PowerShell