paaskanama
paaskanama

Reputation: 53

Powershell strings equal but not equal in try except block

In attempting to understand the logic of try-catch blocks in Powershell, I am experiencing a failure to terminate from a successful pairing of target string to iterated string element from a hashtable.

$stopLoop = $false
$retryWait = 2
$retryCount = 0
$reconnectAttemptMax = 5

$fruits = @('apple','pear','banana','lemon','lime','mango','pineapple','raisins','orange')
$target_fruit = 'pear'
$i = 0

do {
    try {
        if ($fruits[$i] -is $target_fruit ) {
        Write-Host "Found $target_fruit!" }
        $stopLoop = $true
    }
    catch {
        if ($retryCount -eq $reconnectAttemptMax){
            Write-Host "Unable to locate $target_fruit after $retryCount attempts."
            $stopLoop = $true
        }
        else {
            Write-Host "Found $($fruits[$i]) not $target_fruit, retrying in $retryWait seconds..."
            Start-Sleep -Seconds $retryWait
            $retryCount++
            $i++
        }
    }
} while ($stopLoop -eq $false)

When the above code is executed, the second iteration of the loop finds the correct item, but does not terminate from the loop. They are both of String object types, so I assume I am incorrectly nesting the loop criteria.

Result:

Found apple not pear, retrying in 2 seconds...
Found pear not pear, retrying in 2 seconds...
Found banana not pear, retrying in 2 seconds...
Found lemon not pear, retrying in 2 seconds...
Found lime not pear, retrying in 2 seconds...
Unable to locate pear after 5 attempts.

Upvotes: 0

Views: 93

Answers (1)

postanote
postanote

Reputation: 16076

As per my comment regarding the target_fruit assignment.

Clear-Host

$stopLoop            = $false
$retryWait           = 2
$retryCount          = 0
$reconnectAttemptMax = 5
$fruits              = @('apple','pear','banana','lemon','lime','mango','pineapple','raisins','orange')
$target_fruit        = 'DOG'
$i                   = 0

do {
    try {
        if ($fruits[$i] -is $target_fruit ) 
        {"Found $target_fruit!"}
        $stopLoop = $true
    }
    catch 
    {
        if ($retryCount -eq $reconnectAttemptMax)
        {
            Write-Warning -Message "Unable to locate $target_fruit after $retryCount attempts."
            $stopLoop = $true
            Write-Warning -Message 'Exiting the script'
        }
        else 
        {
            "Found $($fruits[$i]) not $target_fruit, retrying in $retryWait seconds..."
            Start-Sleep -Seconds $retryWait
            $retryCount++
            $i++
        }
    }
} while ($stopLoop -eq $false)
# Results
<#
Found apple not DOG, retrying in 2 seconds...
Found pear not DOG, retrying in 2 seconds...
Found banana not DOG, retrying in 2 seconds...
Found lemon not DOG, retrying in 2 seconds...
Found lime not DOG, retrying in 2 seconds...
WARNING: Unable to locate DOG after 5 attempts.
WARNING: Exiting the script
#>

Quick example using CompareTo and your string.

$fruits | 
Where-Object {($PSItem).CompareTo($target_fruit) -eq 0}
# Results
<#
pear
#>

Using you code block a bit more.

$retryWait           = 2
$retryCount          = 0
$reconnectAttemptMax = 5
$fruits              = @('apple','pear','banana','lemon','lime','mango','pineapple','raisins','orange')
$target_fruit        = 'DOG'
$i                   = 0

Try 
{
    do
    {
        Write-Warning -Message "Found $($fruits[$i]) not $target_fruit, retrying in $retryWait seconds..."
        Start-Sleep -Seconds $retryWait
        $retryCount++
        $i++
    }
    until (($fruits[$i]).CompareTo($target_fruit) -eq 0)

    "Found $target_fruit!"
}
Catch
{
    Write-Warning -Message "Unable to locate $target_fruit after $retryCount attempts."
    Write-Warning -Message 'Exiting the script'
    Break
}
# Results
<#
WARNING: Found orange not DOG, retrying in 2 seconds...
WARNING: Found apple not DOG, retrying in 2 seconds...
WARNING: Found pear not DOG, retrying in 2 seconds...
WARNING: Found banana not DOG, retrying in 2 seconds...
WARNING: Found lemon not DOG, retrying in 2 seconds...
WARNING: Found lime not DOG, retrying in 2 seconds...
WARNING: Found mango not DOG, retrying in 2 seconds...
WARNING: Found pineapple not DOG, retrying in 2 seconds...
WARNING: Found raisins not DOG, retrying in 2 seconds...
WARNING: Found orange not DOG, retrying in 2 seconds...
WARNING: Unable to locate DOG after 10 attempts.
WARNING: Exiting the script
#>


Clear-Host

$retryWait           = 2
$retryCount          = 0
$reconnectAttemptMax = 5
$fruits              = @('apple','pear','banana','lemon','lime','mango','pineapple','raisins','orange')
$target_fruit        = 'pear'
$i                   = 0

Try 
{
    do
    {
        Write-Warning -Message "Found $($fruits[$i]) not $target_fruit, retrying in $retryWait seconds..."
        Start-Sleep -Seconds $retryWait
        $retryCount++
        $i++
    }
    until (($fruits[$i]).CompareTo($target_fruit) -eq 0)

    "Found $target_fruit!"
}
Catch
{
    Write-Warning -Message "Unable to locate $target_fruit after $retryCount attempts."
    Write-Host 'Exiting the script' -ForegroundColor Red
    Break
}
# Results
<#
WARNING: Found apple not pear, retrying in 2 seconds...
Found pear!
#>

See also:

Everything you wanted to know about exceptions

Upvotes: 1

Related Questions