about_Trap

簡単な説明

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

詳細な説明

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

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

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

    Note

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

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

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

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

構文

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

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

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

1 つのスクリプトまたはコマンドに複数の trap ステートメントを指定できます。 trap ステートメントは、スクリプトまたはコマンド内の任意の場所に表示できます。

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

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

次の例は、最小限 trap のステートメントです。

trap { 'Error found.' }

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

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

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

TrapTest

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

Error found.
nonsenseString:
Line |
   3 |      nonsenseString
     |      ~~~~~~~~~~~~~~
     | The term 'nonsenseString' is not recognized as a name of a cmdlet,
function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the
path is correct and try again.

次の例には、自動変数を 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:
Line |
   3 |      nonsenseString
     |      ~~~~~~~~~~~~~~
     | The term 'nonsenseString' is not recognized as a name of a cmdlet,
function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the
path is correct and try again.

重要

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

特定のエラーのトラップ

1 つのスクリプトまたはコマンドに複数の 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 型から継承されます。 このステートメントは、不明なコマンドによって発生したエラーをトラップします。 また、他のエラーの種類もトラップします。

エラー オブジェクトを調べることで、エラーの例外の種類を見つけることができます。 次の例は、セッションの最後のエラーの例外の完全な名前を取得する方法を示しています。

nonsenseString
$Error[0].Exception.GetType().FullName
nonsenseString: The term 'nonsenseString' is not recognized as a name of a
cmdlet, function, script file, or executable program. Check the spelling
of the name, or if a path was included, verify that the path is correct
and try again.

System.Management.Automation.CommandNotFoundException

スクリプトには複数の 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:
Line |
   5 |      nonsenseString
     |      ~~~~~~~~~~~~~~
     | The term 'nonsenseString' is not recognized as a name of a cmdlet,
function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the
path is correct and try again.

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

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

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

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

Other terminating error trapped
RuntimeException:
Line |
   5 |  1/$null
     |  ~~~~~~~
     | Attempted to divide by zero.

0 で除算しても、CommandNotFoundException エラーは発生しません。 もう 1 つの trap ステートメントは、終了エラーをトラップし、除算を 0 でトラップします。

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

既定では、終了エラーがスローされると、実行はトラップ ステートメントに転送されます。 ブロックが 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!
RuntimeException:
Line |
   3 |     1/$x
     |     ~~~~
     | Attempted to divide by zero.
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:
Line |
   3 |      NonsenseString
     |      ~~~~~~~~~~~~~~
     | The term 'NonsenseString' is not recognized as a name of a cmdlet,
function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the
path is correct and try again.
function1 was completed

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

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

function function2 {
    NonsenseString
    'function2 was completed'
}

trap { 'An error:' }

function2

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

An error:
NonsenseString:
Line |
   2 |      NonsenseString
     |      ~~~~~~~~~~~~~~
     | The term 'NonsenseString' is not recognized as a name of a cmdlet,
function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the
path is correct and try again.

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

注意

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

次の例では、with whoops 1 実行trapのみです。

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

重要

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

中断を使用してキーワード (keyword)を続行する

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

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

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

break_example
Error trapped
ParentContainsErrorRecordException:
Line |
   6 |      1/$null
     |      ~~~~~~~
     | Attempted to divide by zero.

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

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

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

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

continue_example
Error trapped
Function completed.

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

メモ

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

関連項目