Akaizoku
Akaizoku

Reputation: 472

ErrorAction "SilentlyContinue" does not populate ErrorVariable

Issue

When using -ErrorAction "SilentlyContinue", the error variable is not being populated as described in the following documentation: Handling Errors the PowerShell Way.

Question

How to prevent the error to be displayed as it is with -ErrorAction "Continue" yet still populate the error variable?

Bonus question

Is there a way to append the error to the error variable in order to store more than one of them?

MWE

Script

$ErrorActions = @("Continue", "SilentlyContinue", "Stop")
foreach ($ErrorAction in $ErrorActions) {
    Write-Host -Object $ErrorAction -ForegroundColor "Green"
    Get-Item -Path "C:\tmp\error1" -ErrorAction $ErrorAction -ErrorVariable "ErrorMessage"
    Get-Item -Path "C:\tmp\error2" -ErrorAction $ErrorAction -ErrorVariable "ErrorMessage"
    Write-Host -Object "ErrorVariable" -ForegroundColor "Yellow"
    $ErrorMessage
}

Output

Continue

Get-Item : Cannot find path 'C:\tmp\error1' because it does not exist.

At C:\tmp\mwe.ps1:43 char:5

  • Get-Item -Path "C:\tmp\error1" -ErrorAction $ErrorAction -ErrorVa ...
    
  • ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : ObjectNotFound: (C:\tmp\error1:String) [Get-Item], ItemNotFoundException

    • FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetItemCommand

Get-Item : Cannot find path 'C:\tmp\error2' because it does not exist.

At C:\tmp\mwe.ps1:44 char:5

  • Get-Item -Path "C:\tmp\error2" -ErrorAction $ErrorAction -ErrorVa ...
    
  • ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : ObjectNotFound: (C:\tmp\error2:String) [Get-Item], ItemNotFoundException

    • FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetItemCommand

ErrorVariable

Get-Item : Cannot find path 'C:\tmp\error2' because it does not exist.

At C:\tmp\mwe.ps1:44 char:5

  • Get-Item -Path "C:\tmp\error2" -ErrorAction $ErrorAction -ErrorVa ...
    
  • ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : ObjectNotFound: (C:\tmp\error2:String) [Get-Item], ItemNotFoundException

    • FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetItemCommand

SilentlyContinue

ErrorVariable

Stop

Get-Item : Cannot find path 'C:\tmp\error1' because it does not exist.

At C:\tmp\mwe.ps1:43 char:5

  • Get-Item -Path "C:\tmp\error1" -ErrorAction $ErrorAction -ErrorVa ...
    
  • ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : ObjectNotFound: (C:\tmp\error1:String) [Get-Item], ItemNotFoundException

    • FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetItemCommand

Upvotes: 1

Views: 1409

Answers (1)

codewario
codewario

Reputation: 21468

Using Get-ChildItem as an example:

Get-ChildItem C:\nonexist -EA SilentlyContinue -EV silentErr
[bool]$silentErr # ==> True

As the documentation you linked to mentions, for -ErrorVariable and $ErrorActionPreference controls the following behavior when non-terminating errors occur (these do not affect terminating errors):

  • Continue: Display the error and continue execution.
  • SilentlyContinue: Hide error but still add it to the -ErrorVariable, if specified, and $error stack.
  • Stop: Throws an exception and halts execution. Exceptions may be caught and handled via a try / catch / finally block.
    • Non-terminating errors cannot be normally handled via try / catch / finally because an exception isn't thrown unless -ErrorAction is Stop.
  • Ignore: The error is swallowed with no indication it occurred. Neither -ErrorVariable or the $error stack is updated in this case.
  • Inquire: Ask the operator what to do if an error occurs.

Using the above knowledge, we can still rely on the $error automatic variable and the specified
-ErrorVariable to be populated if the -ErrorAction is SilentlyContinue.

Note: You can also use the $ErrorView variable to further control how errors are displayed in the console.


To answer your sub-question, there is not a mechanism for giving a "named" error stack, but you can use the built-in $error stack to keep track of the errors which occur (and didn't occur under
-EA Ignore). If you want to ensure you only have errors that occur at a certain point onward in your script/session/etc, you can call the following to clear the error variable:

$error.Clear()

Additional Information

Upvotes: 1

Related Questions