powershellerror-handlingtry-catchinvoke-webrequest

How to prevent Invoke-Webrequest from writing to $Error?


I use invoke-webrequest to wait until the API of a program is running and to get an id back from the response of this request. The program takes some time to startup so before the request is posted the request might have already failed 10 times. This code is inside a script block so the contents of $Error are written to a log file. However, these 10 failed web requests are also written to the log file even though they are caught by a try-catch statement.

$notPosted = $true
while ($notPosted) {
    try {
        $postId = Invoke-WebRequest -Uri $url -Method Post -Body $body -UseBasicParsing
        $notPosted = $false
    } catch {
        Start-Sleep -Seconds 1
    }
}

How can I prevent this invoke-webrequest from writing to $Error?

Edit: The reason I want to prevent this invoke-webrequest from writing to $Error is because at the end of the script I want to write all errors to a log file (simular to using transcript). Also when an error occurs a message is send to the user of the console, so that they know something might have gone wrong. In this case nothing has gone wrong, because the error was expected. This might be a more elaborate example:

$job = Start-Job -ScriptBlock {
    $notPosted = $true
    while ($notPosted) {
        try {
            $postId = Invoke-WebRequest -Uri $url -Method Post -Body $body -UseBasicParsing
            $notPosted = $false
        } catch {
            Start-Sleep -Seconds 1
        }
    }
    if ($Error) {
        return $true
    }
}

while($job.State -eq 'running') {
    Write-Host "Still no response"
    Start-Sleep -Seconds 3
}

Write-Host "Job finished"
if (Receive-Job -Job $job) {
    Write-Host "There was an error"
}

Solution

  • Indeed, while you can silence terminating errors (the type of error that a try / catch statement handles), you cannot prevent them from getting recorded in the session-wide collection of error records stored in the automatic $Error variable.

    By contrast, the recording of non-terminating errors can be prevented with -ErrorAction Ignore or $ErrorActionPreference = 'Ignore' (note that setting $ErrorActionPreference to 'Ignore' is only supported in PowerShell (Core) 7); e.g., Get-Item -ErrorAction Ignore NoSuchFile is both silent and does not add an entry to $Error.


    Workaround:

    # Save the current count of session-wide errors.
    $errCountBefore = $Error.Count
    
    # ... run code that (only) emits errors you'd like to ignore
    
    # Restore the previous state of $Error by removing all records that
    # were added.
    # (Note that the errors are recorded in most-recent-first order.)
    $Error.RemoveRange(0, $Error.Count - $errCountBefore)