簡體   English   中英

這是處理管道中的錯誤/異常的正確方法嗎?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM