[英]Is this the correct way to deal with errors/exceptions in pipelines?
這是我最后一個問題的跟進,只是一個澄清要求。
因為ThrowTerminatingError()
將終止cmdlet並停止處理管道中的項目。 什么是處理管道中“問題”對象的正確方法,但您仍想繼續處理其余項目?
我將在這里使用一個非常簡單的示例,考慮以下功能:
Function Do-Something
{
[CmdletBinding()]
Param(
[Parameter(Mandatory=$True,
ValueFromPipeline=$True)]
[int]$value
)
process
{
if($value -eq 3)
{
// Terminate if $value is 3.
}
Write-Output($value)
}
}
現在假設像下面這樣調用此函數...
1..10 | Do-Something
使用throw
:
if($value -eq 3)
{
throw '$value was 3'
}
這是輸出:
1
2
$value was 3
At C:\Users\Me\Desktop\Untitled1.ps1:51 char:12
+ throw '$value was 3'
+ ~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: ($value was 3:String) [], RuntimeException
+ FullyQualifiedErrorId : $value was 3
使用ThrowTerminatingError()
:
if($value -eq 3)
{
$PSCmdlet.ThrowTerminatingError((New-Object System.Management.Automation.ErrorRecord -ArgumentList (new-object System.Exception -ArgumentList ('$value was 3')), 'ValueWas3', 'NotSpecified', $value))
}
生成類似的輸出:
1
2
Do-Something : $value was 3
At C:\Users\Me\Desktop\Untitled1.ps1:57 char:9
+ 1..10 | Do-Something
+ ~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (3:Int32) [Do-Something], Exception
+ FullyQualifiedErrorId : ValueWas3,Do-Something
但是,如果我使用Write-Error和return語句:
if($value -eq 3)
{
Write-Error((New-Object System.Management.Automation.ErrorRecord -ArgumentList (new-object System.Exception -ArgumentList ('$value was 3')), 'ValueWas3', 'NotSpecified', $value))
return
}
這些項目全部進行處理,報告第三個錯誤:
1
2
Do-Something : $value was 3
At C:\Users\Me\Desktop\Untitled1.ps1:58 char:9
+ 1..10 | Do-Something
+ ~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException
,Do-Something
4
5
6
7
8
9
10
這是我應該處理流水線對象問題的正確方法,還是應該查看函數的結構?
基本上,我只想知道如何處理無法處理的管道中的對象,但是我想繼續處理所有剩余的對象。
我想要這樣的原因是在函數的end
,有時我可能想報告哪些項目已成功處理而哪些項目失敗(可能是有原因的)。
編寫PowerShell命令時,有兩種表達錯誤的廣泛選擇: non-terminating
terminating
錯誤和terminating
錯誤。
如果命令可以繼續,請使用non-terminating
錯誤。 例如,您要復制1000個文件,而第一個文件被鎖定。 完全使整個操作失敗是沒有意義的。 在這種情況下,使用Write-Error
並將錯誤信息寫入該文件的Error流,然后繼續復制其他文件就足夠了。
當遇到無法繼續執行的錯誤時,請使用terminating
錯誤。 例如,如果命令的第一步是建立與遠程服務的連接,但服務沒有響應,則您實際上無法繼續。 在終止錯誤的情況下,您的選擇是:A)拋出,B)使用ThrowTerminateError()或C)讓異常轉義命令的實現。 這些是引發(或未捕獲)異常的變體。
順便說一句,是否在Write-Error
之后使用return
語句取決於您是否要為當前管道對象執行更多代碼(也許是清理代碼)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.