錯誤處理
腳本遲早會遇到問題:檔案不存在、網路斷線、權限不足。沒有錯誤處理的腳本會在出錯後繼續往下跑,可能把錯誤的結果寫進檔案或資料庫。本頁說明 PowerShell 有兩種不同的錯誤,以及如何用 try / catch 接住它們。
兩種錯誤:終止與非終止
| 種類 | 行為 | 例子 |
|---|---|---|
| 非終止錯誤(non-terminating) | 顯示紅字錯誤,腳本繼續往下執行 | Get-ChildItem C:\不存在 |
| 終止錯誤(terminating) | 停止目前的執行流程 | throw、語法錯誤、-ErrorAction Stop 的 cmdlet |
大多數 cmdlet 遇到問題時只發出「非終止錯誤」。這也是為什麼光是用 try / catch 包起來,常常接不到錯誤。
try / catch / finally
try {
Get-Content -Path 'C:\不存在.txt' -ErrorAction Stop
'讀取成功' # 上一行出錯就不會執行到這裡
}
catch {
"發生錯誤:$($_.Exception.Message)"
}
finally {
'不論成功或失敗,都會執行(例如關閉連線、清理暫存檔)'
}
關鍵在 -ErrorAction Stop:它把這個 cmdlet 的非終止錯誤升級成終止錯誤,catch 才接得到。
在 catch 區塊裡,$_ 是錯誤記錄(ErrorRecord),常用的屬性有:
| 屬性 | 內容 |
|---|---|
$_.Exception.Message |
錯誤訊息文字 |
$_.Exception.GetType().FullName |
例外型別,可用來分辨不同的錯誤 |
$_.InvocationInfo.ScriptLineNumber |
出錯的行號 |
依例外型別分別處理
try {
Get-Content -Path $path -ErrorAction Stop
}
catch [System.Management.Automation.ItemNotFoundException] {
"找不到檔案:$path"
}
catch {
"其他錯誤:$($_.Exception.Message)"
}
-ErrorAction:控制錯誤時的行為
所有 cmdlet 都有 -ErrorAction 參數:
| 值 | 效果 |
|---|---|
Continue |
預設。顯示錯誤,繼續執行 |
Stop |
升級成終止錯誤,可被 catch 接住 |
SilentlyContinue |
不顯示錯誤,繼續執行(錯誤仍記錄在 $Error) |
Ignore |
完全忽略,連 $Error 都不記錄 |
不想每個 cmdlet 都加參數,可以在腳本開頭統一設定:
這樣整支腳本遇到錯誤就會停下來,是寫正式腳本時很推薦的習慣:出錯就停,比默默繼續更安全。
自己丟出錯誤
throw 產生終止錯誤,呼叫端可以用 try / catch 處理。
檢查上一個指令是否成功
$?:上一個 PowerShell 指令是否成功(True或False)。$LASTEXITCODE:呼叫外部程式(例如git、ping)時,該程式的結束代碼,0 通常代表成功。外部程式失敗不會觸發catch,必須自己檢查:
PowerShell 7 更易讀的錯誤顯示
PowerShell 7 預設用簡潔的格式顯示錯誤($ErrorView 為 ConciseView),一眼就能看到出錯的訊息與位置。需要完整細節時,用 Get-Error 查看最後一個錯誤的所有內容。
推薦影音
官方:PowerShell 7 的新錯誤檢視
簡述:PowerShell 團隊介紹 PowerShell 7 更簡潔、易讀的錯誤顯示方式(約 7 分鐘),對應本頁最後一節,讓你更快從紅字裡找到問題所在。
相關資料
- about_Try_Catch_Finally(官方說明)
- Everything you wanted to know about exceptions(官方深入教學)
- 下一步:腳本與模組