如何在管道中进一步检查异常

时间:2010-05-26 17:32:04

标签: powershell-v2.0

我正在使用New-Object System.Management.Automation.PipelineStoppedException 要停止管道OK..works ..

但是如何在下一个cmdlet中测试是否可以停止?

Foo1 | foo2 | foo3

在foo1停止,但转到foo2。我想测试是否在foo1中停止了在每个函数中停止

function foo1 {
    process {
        try {
            #do
        } catch {
            New-Object System.Management.Automation.PipelineStoppedException
        }
    }
}

仍然会转到下一个cmdlet,因错误而停止我想在每个下一个cmdlet中停止.. :)

谢谢!!!

1 个答案:

答案 0 :(得分:2)

您误解了管道的工作原理。当一系列对象被发送到管道时,每个单独的对象在处理下一个对象之前通过整个管道。请考虑以下功能:

function First() {
    process {
        Write-Host "First: $_";
        $_
    }
}

function Second() {
    process {
        Write-Host "Second: $_";
    }
}

第一个函数输出“First”和管道对象的值,然后传递对象。第二个仅输出“Second”和管道对象。现在,当您将数组推送到由这两个函数组成的管道时,您希望看到什么?

实际结果如下:

PS C:\Users\Lauri> ,1,2,3 | first | second
First: 1
Second: 1
First: 2
Second: 2
First: 3
Second: 3

现在,有了这个信息,我们可以推断出当管道中的函数或cmdlet抛出异常以停止处理时,整个管道就会停止。但我们也可以轻松验证它。让我们修改First如下:

function First() {
    process {
        throw New-Object System.Management.Automation.PipelineStoppedException
    }
}

然后再次尝试相同的管道:

PS C:\Users\Lauri> ,1,2,3 | first | second

结果为空,因为第一个对象传递给“First”的那一刻,它会抛出异常,整个管道都会中止。

总之,您无法测试处理是否在管道中进一步中止,因为执行将永远不会到达。

[编辑]另一个有趣的小问题:首先运行所有函数的Begin块,并且End块都是最后运行的,所以如果你在管道中更高的Process块中抛出一个异常,那么Begin块就是所有管道功能都已经运行:

function First() {
    begin {
        Write-Host "First begin"
    }
    process {
        throw New-Object System.Management.Automation.PipelineStoppedException
    }
    end {
        Write-Host "First end"
    }
}

function Second() {
    begin {
        Write-Host "Second begin"
    }
    process {
        Write-Host "Second: $_"
    }
    end {
        Write-Host "Second end"
    }
}

PS C:\Users\Lauri> ,1,2,3 | first | second
First begin
Second begin

[编辑2]

另一个可能有趣的结果是,如果发生异常并且您希望管道在此之后继续,则需要在catch块中返回捕获它的内容:

function CauseException {
    throw New-Object Exception
}

function First() {
    process {
        try {
            CauseException
        } catch {
            "Error"
        }
    }
}

function Second() {
    process {
        Write-Host "Second: $_"
    }
}

PS C:\Users\Lauri> ,1,2,3 | first | second
Second: Error
Second: Error
Second: Error