2011-07-21 9 views
41

私は最近、素晴らしい作品PowerShellスクリプトを書いた - しかし、私は今、スクリプトをアップグレードし、いくつかのエラーチェック/処理を追加したいのですが - しかし、私はそれはそう最初のハードルで困惑してきました。なぜ次のコードは動作しませんか?のPowershellのtry/catch /最後に

try { 
    Remove-Item "C:\somenonexistentfolder\file.txt" -ErrorAction Stop 
} 

catch [System.Management.Automation.ItemNotFoundException] { 
    "item not found" 
} 

catch { 
    "any other undefined errors" 
    $error[0] 
} 

finally { 
    "Finished" 
} 

エラーは、第二のcatchブロックでキャッチされた - あなたは$error[0]からの出力を見ることができます。明らかに私は最初のブロックでそれをキャッチしたいと思います - 私は何が欠けていますか?ありがとう

答えて

35

-ErrorAction Stopはあなたのために物事を変えています。これを追加して、あなたが得るものを見てください:

Catch [System.Management.Automation.ActionPreferenceStopException] { 
"caught a StopExecution Exception" 
$error[0] 
} 
+0

'$ _。Exception'は' ItemProtocolsStopException'ではなく 'ItemNotFoundException'です。私は 'RuntimeException'から後者のドライブを賭けました。 –

+0

あなたは正しいと思います。私はあなたのスイッチバージョンが好きです。スティーブがやろうとしていることに沿ったもの。 – Bruce

+7

ここで問題となるのは、非終了エラーです。したがって、それが 'ItemNotFoundException'であっても、' ActionPreferencesStopException'でラップされない限り、実際にはスローされません。開発者として、これは私を悩ます。 :) – JasonMArcher

23

これは非常に奇妙です。

私は ItemNotFoundExceptionの基底クラスを経て、どのような だろうキャッチ、それを参照するには、以下の複数の catch ESをテストした:

結局のところ
try { 
    remove-item C:\nonexistent\file.txt -erroraction stop 
} 
catch [System.Management.Automation.ItemNotFoundException] { 
    write-host 'ItemNotFound' 
} 
catch [System.Management.Automation.SessionStateException] { 
    write-host 'SessionState' 
} 
catch [System.Management.Automation.RuntimeException] { 
    write-host 'RuntimeException' 
} 
catch [System.SystemException] { 
    write-host 'SystemException' 
} 
catch [System.Exception] { 
    write-host 'Exception' 
} 
catch { 
    write-host 'well, darn' 
} 

、出力が'RuntimeException'ました。出力'CommandNotFoundException'が正しくこと

try { 
    do-nonexistent-command 
} 
catch [System.Management.Automation.CommandNotFoundException] { 
    write-host 'CommandNotFoundException' 
} 
catch { 
    write-host 'well, darn' 
} 

:私はまた別の例外CommandNotFoundExceptionでそれを試してみました。

(私は再びそれを見つけることができませんでしたが)私は漠然とこれで問題の別の場所で読んで覚えています。例外フィルタリングが正しく機能しなかった場合、最も近いTypeをキャッチし、switchを使用します。以下は、ちょうどExceptionの代わりRuntimeExceptionキャッチ、しかしItemNotFoundExceptionのすべての基本型をチェックし、私の最初の例のswitchと同等である:それが必要として

try { 
    Remove-Item C:\nonexistent\file.txt -ErrorAction Stop 
} 
catch [System.Exception] { 
    switch($_.Exception.GetType().FullName) { 
    'System.Management.Automation.ItemNotFoundException' { 
     write-host 'ItemNotFound' 
    } 
    'System.Management.Automation.SessionStateException' { 
     write-host 'SessionState' 
    } 
    'System.Management.Automation.RuntimeException' { 
     write-host 'RuntimeException' 
    } 
    'System.SystemException' { 
     write-host 'SystemException' 
    } 
    'System.Exception' { 
     write-host 'Exception' 
    } 
    default {'well, darn'} 
    } 
} 

これは、'ItemNotFound'を書き込みます。

+0

コメントスレッドをBruceの答えで見てください。 – JasonMArcher