代码之家  ›  专栏  ›  技术社区  ›  ChiliYago

函数停止处理try catch

  •  -1
  • ChiliYago  · 技术社区  · 6 年前

    为什么即使我正在使用try/catch and continue语句,此函数也会停止处理?

    在下面的例子中,当到达“3”时,我尝试一个无效的get项,希望能捕捉到erroraction stop语句,然后继续到“4”和“5”。

    结果应该是

    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 回复  |  直到 6 年前
        1
  •  0
  •   ArcSet    6 年前

    因为这是在管道中,所以continue退出管道,并尝试移动到对象上方数组中的下一个对象。相反,使用一个将返回到管道中的下一个对象的返回

    continue将在这种情况下工作:

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

    return在这个版本中有效:

    $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 $_
    }
    

    在下面的最后一个示例中,您将看到当您在管道中单击continue时,它将转到 $外数组 是的。它从来没有击中 “外端” 语句,因为管道强制 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"
    }
    
        2
  •  0
  •   user6811411user6811411    6 年前

    整个想法只有在万一的情况下才能奏效

    • 写入输出,
    • 整个if和试图获取项目

    里面 试接球区。

    ## 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
    
        3
  •  0
  •   ChiliYago    6 年前

    不知道为什么,但我发现使用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"