
■ try ~ catch ~ finally
powerShellのVer.2以降では、try ~ catch ~ finallyのエラートラップが使用できるようになったというので、試して見ました。
基本構文はこんな感じですかね。
try {
# 処理です。
} catch [例外] {
# エラートラップです。
} finally {
# 正常、異常に関わらずに、最後に必ず行う処理です。
}
ぶっちゃけると、javaとかと同じですね。catch の指定は複数選択や、多段構造も可能です。
# 複数指定はカンマで区切る
} catch [例外1], [例外2] {
# 多段指定は、catchを複数作る
} catch [例外1] {
} catch [例外2] {
finally は要らないなら書かなくてもOKです。
■ 実験1(正常パターン)
まず、エラーが発生しないようにソースを書いて動かして見ます。
キャッチするエラーは、Exceptionにします(実質的には全てのエラーを拾う)。
Write-Host "処理開始"
try {
# 処理です。
Write-Host "処理を実行します。"
} catch [Exception] {
# エラートラップです。
Write-Host "catchされました。"
} finally {
# 最後に必ず行う処理です。
Write-Host "finallyの処理です。"
}
Write-Host "処理終了"
実行結果は、以下の通りです。
処理開始
処理を実行します。
finallyの処理です。
処理終了
コンソールへの出力内容から、エラートラップされずに動作したようです。
ここまでは、想定内です。
■ 実験2(異常パターン)
throwを使用して、強制的に処理を異常終了させてみます。
Write-Host "処理開始"
try {
# 処理です。
throw 'tryの中でエラーを発生させます。'
} catch [Exception] {
# エラートラップです。
Write-Host "catchされました。"
} finally {
# 最後に必ず行う処理です。
Write-Host "finallyの処理です。"
}
Write-Host "処理終了"
実行結果です。
処理開始
catchされました。
finallyの処理です。
処理終了
きちんとエラートラップが動作したようです。
さらに、異常発生時にもfinallyが動作することを確認しました。
■ 実験3(tryの外で異常)
今度は、tryブロックの外でエラーを発生させてみます。
Write-Host "処理開始"
try {
# 処理です。
Write-Host "処理を実行します。"
} catch [Exception] {
# エラートラップです。
Write-Host "catchされました。"
} finally {
# 最後に必ず行う処理です。
Write-Host "finallyの処理です。"
}
throw 'tryの外でエラーを発生させます。'
Write-Host "処理終了"
実行結果です。
処理開始
処理を実行します。
finallyの処理です。
tryの外でエラーを発生させます。
発生場所 C:\My Documents\ブログ素材\powerShell\エラー処理\エラー処理.ps1:12 文字:6
+ throw <<<< 'tryの外でエラーを発生させます。'
+ CategoryInfo : OperationStopped: (tryの外でエラーを発生させます。:String) []、RuntimeException
+ FullyQualifiedErrorId : tryの外でエラーを発生させます。
エラーの発生個所がtryの外なので、エラートラップが動作しません。
まぁ、当然ですね。
■ 実験4(trapとの組合せ1)
ここからが本題です。
以前にtrapを使用したエラートラップの方法(powerShellでエラーを処理をしてみた)を紹介しましたが、それをtryと併用した場合の動作を見て見ます。
これまでのソースに、trapに必要な項目を追加します。
まず、tryの中でエラーを発生させてみます。
# エラートラップの設定
$ErrorActionPreference = "Stop" # Stop(停止), Inquire ( 問い合わせ ), Continue ( 続行 )
Write-Host "処理開始"
try {
throw 'tryの中でエラーを発生させます。'
} catch [Exception] {
Write-Host "catchされました。"
} finally {
Write-Host "finallyの処理です。"
}
Write-Host "処理終了"
# エラートラップ
trap {
Write-Host "trapでエラー検出。"
}
実行結果です。
処理開始
catchされました。
finallyの処理です。
処理終了
エラーはtryでのみ検出されて、trapではエラーを検出しませんでした。
まぁ、わざわざtryを使うってことは、個別のエラーを検出して何らかの処理をさせることが目的でしょうから、これはこれで正常ですね。
■ 実験5(trapとの組合せ2)
今度は、throwをtryブロックの終了後に実行します。
# エラートラップの設定
$ErrorActionPreference = "Stop" # Stop(停止), Inquire ( 問い合わせ ), Continue ( 続行 )
Write-Host "処理開始"
try {
Write-Host "処理です。"
} catch [Exception] {
Write-Host "catchされました。"
} finally {
Write-Host "finallyの処理です。"
}
throw 'tryの外でエラーを発生させます。'
Write-Host "処理終了"
# エラートラップ
trap {
Write-Host "trapでエラー検出。"
}
実行結果です。
処理開始
処理です。
finallyの処理です。
trapでエラー検出。
tryの外でエラーを発生させます。
発生場所 C:\My Documents\ブログ素材\powerShell\エラー処理\エラー処理3.ps1:12 文字:6
+ throw <<<< 'tryの外でエラーを発生させます。'
+ CategoryInfo : OperationStopped: (tryの外でエラーを発生させます。:String) []、RuntimeException
+ FullyQualifiedErrorId : tryの外でエラーを発生させます。
tryの範囲外でエラーが発生した場合は、trapが機能するようです。
■ 実験6(trapとの組合せ3)
最後に、catchした処理中にエラーが発生した場合の動作確認です。
# エラートラップの設定
$ErrorActionPreference = "Stop" # Stop(停止), Inquire ( 問い合わせ ), Continue ( 続行 )
Write-Host "処理開始"
try {
throw 'tryの中でエラーを発生させます。'
} catch [Exception] {
Write-Host "catchされました。"
throw 'catchでエラーを発生させます。'
Write-Host "catch終了です。"
} finally {
Write-Host "finallyの処理です。"
}
throw 'tryの外でエラーを発生させます。'
Write-Host "処理終了"
# エラートラップ
trap {
Write-Host "trapでエラー検出。"
}
実行結果です。
処理開始
catchされました。
finallyの処理です。
trapでエラー検出。
catchでエラーを発生させます。
発生場所 C:\My Documents\ブログ素材\powerShell\エラー処理\エラー処理3.ps1:9 文字:10
+ throw <<<< 'catchでエラーを発生させます。'
+ CategoryInfo : OperationStopped: (catchでエラーを発生させます。:String) []、RuntimeException
+ FullyQualifiedErrorId : catchでエラーを発生させます。
まず、catchでエラーが拾われます。
catch内部でエラーが発生した場合、即座にfinallyが実行されて、その後で、trapでエラーを拾うようです。
後書き
いろいろと遊んでみましたが、だいたい想定通りの結果になりました。
そもそも、私もjavaでプログラムを組むことがあるので、tryの使い方は迷わないんですよね。
ただ、実装方法については考える必要がありそうですね。
javaの場合、catchする例外の種類をかなり厳密に定義してるんですけど、powerShell(というかスクリプト言語)の場合、エラー発生時は無条件に拾うって方が良いような気も...
まぁ、オブジェクトを操作するような処理を書く場合は、細かいエラートラップを掛けないといけないでしょうけどね。
投稿記事の一覧:http://harikofu.web.fc2.com/
--- blog end ---
スポンサードリンク


