Функция останавливает обработку с помощью Try Catch - PullRequest
0 голосов
/ 28 июня 2018

Почему эта функция останавливает обработку, даже если я использую операторы try / catch и continue?

В следующем примере, когда достигается «три», я пытаюсь получить недопустимый Get-Item в надежде, что будет выполнен оператор Stop-ErrorAction, а затем перейдем к «четыре» и «пять».

Результат должен быть

one
two
four
five

но вместо этого я получаю только первые два значения

one
two

function Get-Array {

    [CmdletBinding(
        SupportsShouldProcess=$false, ConfirmImpact='Medium'
    )]
    param(

        [string[]] $myArray

    )

    begin{

        Set-StrictMode -Version latest

        Write-Verbose ('[{0}] Processing begun ...' -f $MyInvocation.MyCommand)

        Write-Verbose ("Procesing {0} items" -f $myArray.Count)

    }

    process{

        $myArray | ForEach-Object {

            if($_ -eq "three"){

               try
               {
                    Get-Item -Path "x:\foo" -ErrorAction Stop
               }
               catch [System.Exception]
               {
                    Write-Error $_
                    continue;
               }
            } 

            Write-Output $_
        }

        }

    end{

        Write-Verbose ('[{0}] Processing completed.' -f $MyInvocation.MyCommand)
    }

}


$input = @("one","two","three","four","five")
$result = Get-Array -myArray $input -verbose -InformationVariable $info
$result 

# Expect: "one","two","four","five"
# Actual: "one","two"

Ответы [ 3 ]

0 голосов
/ 28 июня 2018

Вся идея может работать только в случае

  • Запись-Вывод,
  • все, если с попыткой получить-Item

находятся внутри блока try catch.

## Q:\Test\2018\06\28\SO_51089096.ps1

function Get-Array {
    [CmdletBinding(
        SupportsShouldProcess=$false, ConfirmImpact='Medium'
    )]
    param(
        [string[]] $myArray
    )
    begin{
        Set-StrictMode -Version latest
        Write-Verbose ('[{0}] Processing begun ...' -f $MyInvocation.MyCommand)
        Write-Verbose ("Procesing {0} items" -f $myArray.Count)
    }
    process {
        $myArray | ForEach-Object {
            try {
                if($_ -eq "three"){
                    Get-Item -Path "x:\foo" -ErrorAction Stop
                }
                Write-Output $_
            } catch [System.Exception] {
                    Write-Error $_
            }
        }
    }
    end {
        Write-Verbose ('[{0}] Processing completed.' -f $MyInvocation.MyCommand)
    }
}

$MyInput = @("one","two","three","four","five")
$result = Get-Array -myArray $MyInput -verbose -InformationVariable $info
$result
# Expect: "one","two","four","five"
# Actual: "one","two"

Пример вывода:

> Q:\Test\2018\06\28\SO_51089096.ps1
AUSFÜHRLICH: [Get-Array] Processing begun ...
AUSFÜHRLICH: Procesing 5 items
Get-Array : Das Laufwerk wurde nicht gefunden. Ein Laufwerk mit dem Namen "x" ist nicht vorhanden.
In Q:\Test\2018\06\28\SO_51089096.ps1:34 Zeichen:11
+ $result = Get-Array -myArray $MyInput -verbose -InformationVariable $ ...
+           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Get-Array
AUSFÜHRLICH: [Get-Array] Processing completed.
one
two
four
five
0 голосов
/ 28 июня 2018

Не уверен, почему, но я обнаружил, что использование цикла for работает, как и ожидалось.

function Get-Array {

    [CmdletBinding(
        SupportsShouldProcess=$false, ConfirmImpact='Medium'
    )]
    param(

        [string[]] $myArray

    )

    begin{

        Set-StrictMode -Version latest

        Write-Verbose ('[{0}] Processing begun ...' -f $MyInvocation.MyCommand)

        Write-Verbose ("Procesing {0} items" -f $myArray.Count)

    }

    process{
`
        for($i=0;$i -lt $myArray.Count;$i++) {

            if($myArray[$i] -eq "three"){

               try
               {
                    Get-Item -Path "x:\foo" -ErrorAction Stop
               }
               catch [System.Exception]
               {
                    Write-Error $myArray[$i]
                    continue;
               }
            } 


            Write-Output $myArray[$i]
        }


    }

    end{

        Write-Verbose ('[{0}] Processing completed.' -f $MyInvocation.MyCommand)
    }

}


$input = @("one","two","three","four","five")



$result = Get-Array -myArray $input -verbose -InformationVariable $info
$result 

# Expect: "one","two","four","five"
# Actual: "one","two"
0 голосов
/ 28 июня 2018

Поскольку он находится в канале, продолжение выходит из канала и пытается перейти к следующему объекту в массиве над объектом. Вместо этого используйте Return, который вернется к следующему объекту в трубе

Продолжить будет работать в этой ситуации:

foreach($item in $OutsideArray){
    if($item -eq "three"){
        continue
    }
    $item
}

Возврат будет работать в этом:

$InsideArray  = @("one","two","three","four","five")
$InsideArray | ForEach-Object {    
    if($_ -eq "three"){    
        try
        {
            Get-Item -Path "x:\foo" -ErrorAction Stop
        }
        catch [System.Exception]
        {
            Write-Error $_
            return
        }
    }     
    Write-Output $_
}

В последнем приведенном ниже примере вы увидите, что при нажатии продолжения в трубе он переходит к следующему элементу в $ OutsideArray . Он никогда не попадет в оператор "Внешний конец" , потому что канал заставляет ForEach перейти к следующему числу.

foreach($item in $OutsideArray){
    "Outside Start :  $item"
    $InsideArray  = @("one","two","three","four","five")
    $InsideArray | ForEach-Object {
        if($_ -eq "three"){
            try
            {
                Get-Item -Path "x:\foo" -ErrorAction Stop
            }
            catch [System.Exception]
            {
                continue
            }
        } 
        "Inside : $_"
    }
    "Outside End :  $item"
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...