Как проверить на исключение далее вниз конвейер

Я использую Ново-объектную Систему. Управление. Автоматизация. PipelineStoppedException Для остановки конвейера хорошо.. работы..

Но как я могу протестировать в следующем cmdlet, если был остановлен?

Foo1 | foo2 | foo3

Остановитесь в foo1, но переходит к foo2. Я хочу протестировать, если был остановлен в foo1 для остановки также в каждой функции

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

и все еще идя в следующий cmdlet, как зашел в ошибку, которую я хочу остановить в каждом затем cmdlets..:)

Спасибо!!!

1
задан Rytmis 26 May 2010 в 17:59
поделиться

1 ответ

Вы неправильно поняли, как работают конвейеры. Когда последовательность объектов отправляется в конвейер, каждый отдельный объект проходит через весь конвейер до обработки следующего объекта. Рассмотрим следующие функции:

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

Теперь, имея под рукой эту информацию, мы можем сделать вывод, что когда функция или командлет в конвейере вызывает исключение, чтобы остановить обработку, весь конвейер останавливается. Но это тоже легко проверить.Давайте изменим First следующим образом:

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

, а затем снова попробуем тот же конвейер:

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

Результат пуст, потому что в момент, когда первый объект передается в «First», он генерирует исключение, и весь конвейер прерывается.

Таким образом, вы не можете проверить, была ли обработка прервана дальше по конвейеру,потому что казнь никогда не дойдет до этого.

[Edit] Еще один интересный лакомый кусочек: блоки 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

[Edit 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
2
ответ дан 3 September 2019 в 00:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: