次の方法で共有


about_Trap

簡単な説明

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

長い説明

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

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

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

    注意

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

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

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

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

構文

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

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

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

スクリプトまたはコマンドには、複数の 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 時点を超えて実行が進んでいなくても、そのブロック内のすべてのステートメントにステートメントが適用されます。 たとえば、スクリプトの最後に を trap 定義し、最初のステートメントでエラーをスローしても、 が trapトリガーされます。

特定のエラーのトラップ

スクリプトまたはコマンドには、複数の trap ステートメントを含めることができます。 は、特定の 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 は関数の実行を再開します。 が ステートメントの後にtrap完了していることにFunction1注意してください。

この動作を、同じエラーとステートメントを持つ次の例と 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 に定義された構文 (スクリプト ブロック内で最も高い) が使用されます。

次の例では、 がwhoops 1実行されている trap だけです。

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

重要

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

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

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

ステートメントリストにステートメントを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 が再開されます。これは、 または の場合breakcontinue同様です。 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/catch してトラップを定義するブロックを使用 catch します。 ステートメントは catch 、関連付けられた try ステートメント内のコードにのみ適用されます。 詳細については、「 about_Try_Catch_Finally」を参照してください。

こちらもご覧ください