私のマシンでは、次のコード スニペットのそれぞれが、標準出力 "1" と "2" に出力する代わりにスローと例外をスローします。例外がキャッチされないのはなぜですか?
try {
[int]$a = 1/0
}
catch {
write 1
}
finally {
write 2
}
try {
[int]$a = 1/0
}
catch [System.Exception] {
write 1
}
finally {
write 2
}
私のマシンでは、次のコード スニペットのそれぞれが、標準出力 "1" と "2" に出力する代わりにスローと例外をスローします。例外がキャッチされないのはなぜですか?
try {
[int]$a = 1/0
}
catch {
write 1
}
finally {
write 2
}
try {
[int]$a = 1/0
}
catch [System.Exception] {
write 1
}
finally {
write 2
}
定数を使用しているため、インタープリターは結果を事前計算しようとし、ゼロ除算エラーで失敗します。あなたのコードは実行さえされないので、トラップするものは何もありません。
変数を使用するようにコードを変更し、強制的に実行することで、これを自分で確認できます。
try {
$divisor = 0
[int]$a = 1/$divisor
}
catch {
write 1
}
finally {
write 2
}
Windows PowerShell in Action (p.257)より
この例では、1/$null を使用しています。単純に 1/0 ではなくこれを行う理由は、PowerShell インタープリターが定数式の折りたたみと呼ばれる処理を行うためです。
定数値のみを含む式を調べます。式が見つかると、コンパイル時にその式を 1 回評価するため、実行時に再度実行して時間を無駄にする必要はありません。
これは、ゼロによる除算などの不可能な式がキャッチされ、解析エラーとして扱われることを意味します。構文解析エラーは、対話的に入力されたときにキャッチできず、ログに記録されないため、良い例にはなりません。(あるスクリプトが別のスクリプトを呼び出し、そのスクリプトにこれらのエラーのいずれかがある場合、呼び出し元のスクリプトはそれをキャッチできますが、解析中のスクリプトはそれをキャッチできません。)
v2 の RuntimeException はキャッチできません。v3 で修正されました。
ゼロ除算はこのカテゴリに分類されます。
その種の行で例外をスローしようとすることができます:trap { "Your Exception" } 1/0
これは例外「0で割る」をスローします。あなたのコードが例外をスローしない理由はよくわかりませんが._.
PS: そうあるべきじゃないのcatch [System.SystemException]
?:)